1

この例、特にクライアントを適応させています。コードとそれが生成するエラーに従って、問題が何であると私が思うかをお話しします。

> {-# LANGUAGE OverloadedStrings #-}
> import Network.HTTP.Conduit
> ( http, parseUrl, newManager,def, withManager, RequestBody (RequestBodyLBS)
> , requestBody, method, Response (..)
> )
> import Data.Aeson (Value (Object, String))
> import Data.Aeson.Parser (json)
> import Data.Conduit
> import Data.Conduit.Attoparsec (sinkParser)
> import Control.Monad.IO.Class (liftIO)
> import Control.Monad.Trans.Class (lift)
> import Data.Aeson (encode, (.=), object)


> main :: IO ()
> main = withManager $ \manager -> do
>    value <- makeValue
> -- We need to know the size of the request body, so we convert to a
> -- ByteString
>    let valueBS = encode value
>    req' <- parseUrl "http://10.64.16.6:3000/"
>    let req = req' { method = "POST", requestBody = RequestBodyLBS valueBS }
>    Response status version headers body <- http req manager
>    resValue <- body $$ sinkParser json
>    handleResponse resValue

> -- Application-specific function to make the request value
> makeValue :: ResourceT IO Value
> makeValue = return $ object
>    [ ("foo" .= ("bar" :: String))
>    ]

> -- Application-specific function to handle the response from the server
> handleResponse :: Value -> ResourceT IO ()
> handleResponse foo = do  
>    _ <- lift (print foo)
>    return ()

No instance for (Control.Monad.Trans.Class.MonadTrans ResourceT)
  arising from a use of `lift'
Possible fix:
  add an instance declaration for
  (Control.Monad.Trans.Class.MonadTrans ResourceT)
In a stmt of a 'do' block: _ <- lift (print foo)
In the expression:
  do { _ <- lift (print foo);
       return () }
In an equation for `handleResponse':
    handleResponse foo
      = do { _ <- lift (print foo);
             return () }

ここに問題があります。エラーは Control.Monad.Trans.Class.MonadTrans ResourceT のインスタンスがないことを示しています

しかし、このドキュメントのおかげで、あると思います。では、どこで問題が発生したのでしょうか。

以下で述べたように、何かジャンクが起こっていますControl.Monad.Trans.Resource

ResourceTイントロスペクションの結果がこちら。

*Main Control.Monad.Trans.Resource> :i ResourceT
newtype ResourceT m a
  = Control.Monad.Trans.Resource.ResourceT (GHC.IORef.IORef
                                              Control.Monad.Trans.Resource.ReleaseMap
                                            -> m a)
    -- Defined in `Control.Monad.Trans.Resource'
instance Monad m => Monad (ResourceT m)
  -- Defined in `Control.Monad.Trans.Resource'
instance Functor m => Functor (ResourceT m)
  -- Defined in `Control.Monad.Trans.Resource'
instance MonadBaseControl b m => MonadBaseControl b (ResourceT m)
  -- Defined in `Control.Monad.Trans.Resource'
instance MonadThrow m => MonadThrow (ResourceT m)
  -- Defined in `Control.Monad.Trans.Resource'

のバージョンresourcet

[mlitchard@Boris Boris]$ ghc-pkg list resourcet
WARNING: there are broken packages.  Run 'ghc-pkg check' for more details.
/usr/lib/ghc-7.4.1/package.conf.d
/home/mlitchard/.ghc/x86_64-linux-7.4.1/package.conf.d
   resourcet-0.3.2.1

続行する方法についてのアイデアはありますか?MonadTrans ResourceT のインスタンスはどこにありますか?

4

2 に答える 2

4

私が賭け屋なら、いくつかのライブラリの複数のバージョンがインストールされていると思います。たとえば、バージョン 0.2 と 0.3 のトランスフォーマーがあり、resourcet がバージョン 0.2 に対してビルドされているとします。import Control.Monad.Trans.Class (lift)のバージョン 0.3 をインポートするコードを作成するとき、lift関連するインスタンスはありません。

これをテストする最も簡単な方法は、コードをキャバリゼーションすることです。Cabal は、適切なバージョンのライブラリが含まれていることを確認します。

于 2012-05-24T03:53:40.623 に答える
2

編集:この回答は問題を解決しません。インポートはインスタンスを解決する必要がありますが、まだ解決しません。これは、GHC または他のシステムのバグのようです。

モジュールは便宜上Data.Conduitのみ再エクスポートResourceTします。リソースモナドトランスフォーマーは別のパッケージで定義されていますresourcetconduitそのため、クラス インスタンスを再エクスポートしません (どうやら?)。Control.Monad.Trans.Resource関連するクラス インスタンスにアクセスするには、手動でインポートする必要があります。もちろん、これは次の構文で実行できます。

import Control.Monad.Trans.Resource () -- Only import instances
于 2012-05-23T23:45:14.033 に答える