Monad类型不匹配

时间:2015-07-01 01:23:08

标签: haskell monads

我试图在Spock应用程序中使用IO monad。以下代码无法编译:

get "api/entities" $ do
  entities <- loadEntities
  let e1 : xs = entities
  text $ note e1

loadEntities的类型为IO [Entity]

错误为Couldn't match type ‘ActionT IO ()’ with ‘t0 -> IO b0’

Spock是否使用IO以外的monad?如果是这样,我如何获得loadEntities的结果?

1 个答案:

答案 0 :(得分:4)

写答案让人们可以看到更好的解释。

如果你看get它有类型。

get :: MonadIO m => SpockRoute -> ActionT m () -> SpockT m ()

ActionT是一个monad转换器,它在内部monad中需要一个MonadIO的实例。如果我们查看类型类MonadIO它有一个函数

liftIO :: IO a -> m a

这意味着您调用的每个函数都使用IO a执行该堆栈中liftIO类型的函数。 ActionT也有MonadIO的实例,这是您在此处用来调用IO函数的实例。所以要调用loadEntities你必须

entities <- liftIO loadEntities

如果您结束调用某个特定功能,那么您可以创建一个单独的模块导入它,并导出一个更友好的模块。

module Lifted (loadEntities) where

import qualified SomeModule as IO

loadEntities :: MonadIO m => m Entities
loadEntities = liftIO IO.loadEntities

这将使您不必总是使用liftIO