2012-11-02 13 views
5

これは、おそらくIO()モナドと関係するハスケルの新しい質問です。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

ハッシュスタックは分かりませんが、おそらく 'liftIO $ readFile tmp'を使う必要があります。 – hammar

+1

他の人は言っていますが、あなたは「liftIO」が必要です。私はクラッシュコースにこのセクションを追加します。 – stepcut

答えて

11
No instance for (Happstack.Server.Internal.Monads.WebMonad 
         Response IO) 

翻訳:あなたのdoブロックはIOモナドではなく、他のモナドです。幸いなことに、それはMonadIOのインスタンスであることが判明:

class Monad m => MonadIO m where 
    liftIO :: IO a -> m a 

ご覧のとおり、あなたのケースで、あなただけの必要があるので、このような場合は、単純に、自分自身の中にIOモナドから「リフト」IOアクションへの道を提供します:

contents <- liftIO $ readFile tmp 

liftIOの実装が明らかにmによって異なりますが、一般的なモナド変圧器スタックでは、内部IOモナドを取得するliftliftIOを使用しています。例えば、implementations for the other monad transformers in the Transformers libraryを参照されたい。

+0

この提案を試した後、質問に編集を追加しました。 'liftIO'を追加するほど簡単ではないようです。 – Inaimathi

+0

postFileのタイプは何ですか? – Fixnum

+0

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

関連する問題