2012-11-02 63 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