使用HTTP管道时出现Haskell类型错误

使用HTTP管道时出现Haskell类型错误,haskell,http-conduit,Haskell,Http Conduit,我正在为一个YesSOD应用程序进行OAuth2身份验证,我遇到了一个我真的不理解的类型错误。代码目前已被破坏,我有一些::IO()和未定义的来帮助我隔离类型错误,但相关代码是: getAccessToken :: Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token) getAccessToken manager oa code = do let (uri, defaultBo

我正在为一个YesSOD应用程序进行OAuth2身份验证,我遇到了一个我真的不理解的类型错误。代码目前已被破坏,我有一些
::IO()
未定义的
来帮助我隔离类型错误,但相关代码是:

getAccessToken :: Manager -> OAuth2 -> ExchangeToken -> IO (OAuth2Result Errors OAuth2Token)
getAccessToken manager oa code = do

  let (uri, defaultBody) = accessTokenUrl oa code
  let body = defaultBody <> [ ("client_id", TE.encodeUtf8 . oauthClientId $ oa )
                            , ("client_secret", TE.encodeUtf8 . oauthClientSecret $ oa)
                            , ("resource", TE.encodeUtf8 . oauthClientId $ oa)
                            ]

  response <- performOAuth2PostRequest manager oa uri body

  return undefined

performOAuth2PostRequest :: Manager -> OAuth2 -> URI -> PostBody -> IO (Response ByteString)
performOAuth2PostRequest manager oa uri body  = do
  defaultReq <- uriToRequest uri

  let addBasicAuth = applyBasicAuth (TE.encodeUtf8 . oauthClientId $ oa)
                                    (TE.encodeUtf8 . oauthClientSecret $ oa)

  let req = (addBasicAuth . updateRequestHeaders Nothing) defaultReq

  (httpLbs (urlEncodedBody body req) manager) :: IO (Response ByteString)
这证实了我的理解,即
httpLbs
应该产生
MonadIO m=>m(通过testring进行响应)

但我得到的错误是:

• Couldn't match type ‘Response
                         Data.ByteString.Lazy.Internal.ByteString’
                 with ‘IO (Response ByteString)’
  Expected type: Manager -> IO (Response ByteString)
    Actual type: Manager
                 -> Response Data.ByteString.Lazy.Internal.ByteString
• The function ‘httpLbs’ is applied to two arguments,
  its type is ‘Request
               -> m1 (Response Data.ByteString.Lazy.Internal.ByteString)’,
  it is specialized to ‘Request
                        -> Manager -> Response Data.ByteString.Lazy.Internal.ByteString’

为什么GHC专门负责
m
响应
而不是
IO
?如何修复它?

您没有包含导入语句,因此很难调试它。不过我最好的猜测是您已经导入了
Network.HTTP.Simple
,它提供的函数不需要显式的
管理器
参数。我从提供预期类型的错误消息中猜测:

Request -> m1 (Response Data.ByteString.Lazy.Internal.ByteString)

解决方案:要么更改导入,要么删除
管理器
参数。

据我所知,实际问题是预期的类型是严格的
ByteString
,而实际的类型是惰性的
ByteString
(编译器通过打印完全限定的类型来帮助指示它是不同的类型)。然而,这个错误似乎是假的,因为没有办法将
httpLbs
的类型专门化为
Request->Manager->Response Lazy那么实际的实例化将是
…->Response(Response Lazy.ByteString)
。旁白:您在最后一行中给出的类型注释没有使用
ScopedTypeVariables
,因为
IO(Response ByteString)
不包含任何类型变量;这也是完全多余的,因为函数上的类型签名已经给出了类型。
Request -> m1 (Response Data.ByteString.Lazy.Internal.ByteString)