[英]Haskell Type Error while using HTTP-Conduit
I am working on OAuth2 authentication for a Yesod application and I am having a type error that I really really don't understand. 我正在为Yesod应用程序进行OAuth2身份验证,但遇到了我真的不理解的类型错误。 The code is broken at the moment, and I have a few
:: IO ()
's and undefined
s thrown around to help me isolate the type error, but the relevant code is: 目前,代码已损坏,并且抛出了
:: IO ()
和undefined
,以帮助我隔离类型错误,但是相关代码为:
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)
Notice that I am specifically setting the type of the httpLbs (urlEnc...) manager
action as an IO (Response ByteString)
using the ScopedTypeVariables
extension. 请注意,我使用
ScopedTypeVariables
扩展名专门将httpLbs (urlEnc...) manager
操作的类型设置为IO (Response ByteString)
ScopedTypeVariables
。 Also, that line of code should be an IO action because it's being performed at the top level of an IO action. 另外,该行代码应该是IO操作,因为它是在IO操作的顶层执行的。
In fact, I ran a GHCi session and did: 实际上,我进行了GHCi会议并做了:
Network.OAuth.OAuth2.HttpClient Network.OAuth.OAuth2.Internal
Network.HTTP.Conduit Data.Functor Prelude> :t httpLbs
httpLbs
:: Control.Monad.IO.Class.MonadIO m =>
Request
-> Manager -> m (Response Data.ByteString.Lazy.Internal.ByteString)
Which confirms my understanding that httpLbs
should yield a MonadIO m => m (Response ByteString)
. 这证实了我的理解,即
httpLbs
应该产生MonadIO m => m (Response ByteString)
。
But here is the error I get: 但是这是我得到的错误:
• 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’
Why is GHC specializing m
to Response
instead of IO
? 为什么GHC将
m
专门用于Response
而不是IO
? How do I fix it? 我如何解决它?
You haven't included your import statements, making it difficult to debug this. 您尚未包含import语句,因此很难调试它。 My best guess though is that you've imported
Network.HTTP.Simple
, which provides functions that do not require an explicit Manager
argument. 不过,我最好的猜测是您已导入
Network.HTTP.Simple
,它提供了不需要显式Manager
参数的函数。 I'm guessing this from the error message providing the expected type: 我从提供预期类型的错误消息中猜测出这一点:
Request -> m1 (Response Data.ByteString.Lazy.Internal.ByteString)
Solution: either change the import, or drop the Manager
argument. 解决方案:更改导入,或删除
Manager
参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.