2012-11-02 27 views
5

这是一个Haskell newb问题,可能与IO() monad有关。Happstack显示读取文件

我有一个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再次修复它。

+2

不知道Happstack,但您可能需要使用'liftIO $ readFile tmp'.' – hammar

+1

正如其他人所说的,您只需要'liftIO'。我会在这个上添加一个部分到速成班。 – stepcut

回答

11
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行动统一到自身,所以你的情况,你只需要:

contents <- liftIO $ readFile tmp 

liftIO的实施显然取决于m,但在一个典型的单子转换堆栈它使用liftliftIO去里面的IO单子;例如参见implementations for the other monad transformers in the Transformers library

+0

尝试此建议后,在问题中添加了一个编辑;它似乎不像添加'liftIO'那么简单。 – Inaimathi

+0

postFile的类型是什么? – Fixnum

+0

'Happstack.Server.Internal.Monads.ServerPartT IO String'(':''t' in'ghci' reports'Happstack.Server.Internal.Monads.ServerPartT IO [Char]') – Inaimathi