我看到一些涉及 monad 实例的奇怪行为。我正在编写一个快照应用程序,并且在我的一个处理程序中,除非我创建一个函数,否则它不会编译。
withManager
像这样直接在我的处理程序中调用:
authenticateLanding :: Handler App App ()
authenticateLanding = do
req <- getRequest
oir <- liftIO $ withManager $ OpenId.authenticateClaimed (convertParams req)
writeBS (fromString $ show oir)
导致此编译时错误
openIDTrial.hs:120:25:
No instance for (Control.Monad.Trans.Control.MonadBaseControl
IO m1)
arising from a use of `withManager'
Possible fix:
add an instance declaration for
(Control.Monad.Trans.Control.MonadBaseControl IO m1)
In the expression: withManager
In the second argument of `($)', namely
`withManager $ OpenId.authenticateClaimed (convertParams req)'
In a stmt of a 'do' block:
oir <- liftIO
$ withManager $ OpenId.authenticateClaimed (convertParams req)
但是,如果我把它放在一个函数中,那么我不会得到那个错误
claim params = liftIO $ withManager $ OpenId.authenticateClaimed (params)
authenticateLanding :: Handler App App ()
authenticateLanding = do
req <- getRequest
oir <- claim (convertParams req)
writeBS (fromString $ show oir)
这一点没有任何意义,因为声明函数看起来不会为编译器添加任何额外信息。