Happstack显示读取文件

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变换器堆栈中它使用liftliftIO进入内部的IO monad; 例如,变形金刚库中其他monad变换器实现.