5

IO()これはおそらくモナドに関係するHaskellの初心者の質問です。

Happstack.Serverファイルのアップロードに対する応答を生成する関数がプログラムにあります。

postFile = do methodM POST
              decodeBody filePolicy
              (tmp, name, meta) <- lookFile "upload"
              ok $ concat ["A file! ", tmp, " || ", name, " || ", show meta]

それはうまくいきます。ここで、アップロードされたファイルのコンテンツと、そのローカルtempname、元の名前、およびコンテンツタイプのメタデータを表示したいと思います。これはすべてブロックで行われているので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修正しました。

4

1 に答える 1

12
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ます。たとえば、Transformersライブラリにある他のモナド変換子の実装を参照してください。

于 2012-11-02T05:01:32.443 に答える