Ina*_*thi 5 file-io haskell happstack
这是一个Haskell新问题,可能与IO()monad有关.
我在一个Happstack.Server为文件上传生成响应的程序中有一个函数.
postFile = do methodM POST
decodeBody filePolicy
(tmp, name, meta) <- lookFile "upload"
ok $ concat ["A file! ", tmp, " || ", name, " || ", show meta]
Run Code Online (Sandbox Code Playgroud)
这很好.现在,我希望它显示上传文件的内容以及本地临时名称,原始名称和内容类型元数据.我假设因为这一切都发生在一个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]
Run Code Online (Sandbox Code Playgroud)
但这给我带来了一连串的错误,这似乎告诉我一些事情随着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";
.... }
...
Run Code Online (Sandbox Code Playgroud)
我不确定这里出了什么问题.任何人都可以教育我吗?
EDIT3:
那会让我学会妄下结论.
我得到的其他错误都是由于库安装不正确造成的.清除我的~/.ghc,然后happstack重新安装修复它.
Fix*_*num 11
No instance for (Happstack.Server.Internal.Monads.WebMonad
Response IO)
Run Code Online (Sandbox Code Playgroud)
翻译:你的 do -block不是IO monad而是其他一些monad.幸运的是,它原来是MonadIO的一个实例:
class Monad m => MonadIO m where
liftIO :: IO a -> m a
Run Code Online (Sandbox Code Playgroud)
如您所见,这样的实例只是提供了一种从IO monad"提升"IO动作到自身的方法,因此在您的情况下,您只需要:
contents <- liftIO $ readFile tmp
Run Code Online (Sandbox Code Playgroud)
实现liftIO显然取决于m,但在一个典型的monad变换器堆栈中它使用lift并liftIO进入内部的IO monad; 例如,变形金刚库中其他monad变换器的实现.