为什么把这个liftIO放在一个函数中,但直接调用不行?

Dan*_*Man 5 haskell

我看到一些涉及monad实例的奇怪行为.我正在编写一个快照应用程序,在我的一个处理程序中,除非我创建一个函数,否则它将无法编译.

withManager直接在我的处理程序中调用如下:

authenticateLanding :: Handler App App ()
authenticateLanding = do
    req <- getRequest
    oir <- liftIO $ withManager $ OpenId.authenticateClaimed (convertParams req)
    writeBS (fromString $ show oir)
Run Code Online (Sandbox Code Playgroud)

导致此编译时错误

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)
Run Code Online (Sandbox Code Playgroud)

但是,如果我把它放在一个函数中,那么我不会得到那个错误

claim params = liftIO $ withManager $ OpenId.authenticateClaimed (params)

authenticateLanding :: Handler App App ()
authenticateLanding = do
    req <- getRequest
    oir <- claim (convertParams req)
    writeBS (fromString $ show oir)
Run Code Online (Sandbox Code Playgroud)

关于这一点没有任何意义,因为声明函数不会为编译器添加任何额外信息.