我正在尝试在 Spock 应用程序中使用 IO monad。以下代码无法编译:
\n\nget "api/entities" $ do\n entities <- loadEntities\n let e1 : xs = entities\n text $ note e1\nRun Code Online (Sandbox Code Playgroud)\n\nloadEntities有类型IO [Entity]
错误是Couldn\'t match type \xe2\x80\x98ActionT IO ()\xe2\x80\x99 with \xe2\x80\x98t0 -> IO b0\xe2\x80\x99
Spock 是否使用 IO 以外的 monad?如果是这样,我如何获得loadEntities的结果?
\n写下答案,以便人们可以看到更好的解释。
如果你看一下get它的类型。
get :: MonadIO m => SpockRoute -> ActionT m () -> SpockT m ()
Run Code Online (Sandbox Code Playgroud)
ActionT是一个 monad 转换器,它要求内部 monad 中有一个 的实例MonadIO。如果我们看一下类型类,MonadIO它有一个函数
liftIO :: IO a -> m a
Run Code Online (Sandbox Code Playgroud)
IO a这意味着您通过使用调用执行该堆栈中类型的每个函数liftIO。ActionT有一个 iso 的实例MonadIO,它是您在此处用于调用 IO 函数的实例。所以要打电话loadEntities你必须
entities <- liftIO loadEntities
Run Code Online (Sandbox Code Playgroud)
如果您结束了多次调用某个函数,您可以创建一个单独的模块,将其导入合格的模块并导出一个更友好的模块。
module Lifted (loadEntities) where
import qualified SomeModule as IO
loadEntities :: MonadIO m => m Entities
loadEntities = liftIO IO.loadEntities
Run Code Online (Sandbox Code Playgroud)
这将使您不必总是使用liftIO
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |