这是一个 Haskell 新手问题,可能与 IO()
相关。单子(monad)。
我在 Happstack.Server
中有一个函数生成文件上传响应的程序。
postFile = do methodM POST
decodeBody filePolicy
(tmp, name, meta) <- lookFile "upload"
ok $ concat ["A file! ", tmp, " || ", name, " || ", show meta]
这很好用。现在,我希望它显示上传文件的内容以及它的本地临时名称、原始名称和内容类型元数据。我假设因为这一切都发生在
do
阻止,我可以postFile = do methodM POST
decodeBody filePolicy
(tmp, name, meta) <- lookFile "upload"
contents <- readFile tmp
ok $ concat ["A file! ", tmp, " || ", name, " || ", show meta, "\n\n", contents]
但这给了我一串错误,似乎告诉我
decodeBody
出了点问题称呼。...
/home/inaimathi/projects/happstack-tutorial/parameters.hs:23:15:
No instance for (Happstack.Server.Internal.Monads.WebMonad
Response IO)
arising from a use of `decodeBody'
Possible fix:
add an instance declaration for
(Happstack.Server.Internal.Monads.WebMonad Response IO)
In a stmt of a 'do' block: decodeBody filePolicy
In the expression:
do { methodM POST;
decodeBody filePolicy;
(tmp, name, meta) <- lookFile "upload";
contents <- readFile tmp;
.... }
In an equation for `postFile':
postFile
= do { methodM POST;
decodeBody filePolicy;
(tmp, name, meta) <- lookFile "upload";
.... }
...
我不确定这里出了什么问题。有人可以教育我吗?
EDIT3:
这将让我学会贸然下结论。
我得到的其他错误都是由于安装不正确的库引起的。清理我的
~/.ghc
,然后安装 happstack
再次修复它。
最佳答案
No instance for (Happstack.Server.Internal.Monads.WebMonad
Response IO)
翻译:您的
do
-block 不是 IO 单子(monad),而是其他单子(monad)。幸运的是,它原来是 MonadIO 的一个实例:class Monad m => MonadIO m where
liftIO :: IO a -> m a
如您所见,这样的实例只是提供了一种将 IO 操作从 IO 单子(monad)“提升”到自身的方法,因此在您的情况下,您只需要:
contents <- liftIO $ readFile tmp
liftIO
的执行显然取决于 m
,但在典型的 monad 变压器堆栈中,它使用 lift
和 liftIO
到达里面的 IO monad;例如,参见 implementations for the other monad transformers in the Transformers library .
关于haskell - Happstack 显示一个读取的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13188864/