使用HTTP管道时出现Haskell类型错误
我正在为一个YesSOD应用程序进行OAuth2身份验证,我遇到了一个我真的不理解的类型错误。代码目前已被破坏,我有一些使用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
::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)