2012-05-23 5 views
1

특히이 클라이언트를 example에 적용하고 있습니다. 코드와 오류가 발생한 후 문제가 있다고 생각하는 전화를 드리겠습니다.ResourceT의 문제 해결

> {-# 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

에 대한 인스턴스가 없다고 말합니다 그러나 나는 인해 documentation에 있다고 생각합니다. 어디서 잘못 됐나요? 언급 한 바와 같이

아래 여기 ResourceT 자기 반성의 결과이다 Control.Monad.Trans.Resource

으로 계속 뭔가 janke있다. 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' 

버전은

[[email protected] 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의 인스턴스는 어디에 있습니까?

+0

다음 코드를 사용하면 동일한 결과가 나타납니다. 이것은 매우 이상합니다 :'foo :: ResourceT IO(); foo = 리프트 $ return()'. 결함이있는 패키지 데이터베이스와 관련이 없습니다. – dflemstr

+0

나는 이것이 GHC 나 다른 시스템에서 버그가되어야한다고 결론을 내렸다. 이것에 대해 더 많은 지식을 가진 누군가가 나를 교정 할 수 있습니다. – dflemstr

+0

패키지 작성자에게 전화를 걸도록 요청합니다. –

답변

2

편집 :이 대답은 문제를 해결하지 못하지만 가져 오기를 수행해도 여전히 인스턴스가 해결되지 않습니다. 이것은 GHC 나 다른 시스템의 버그 인 것 같습니다.

Data.Conduit 모듈은 편의를 위해 ResourceT 만 다시 내보내기합니다. 리소스 모나드 변환기는 별도의 패키지 resourcet에 정의되어 있습니다. conduit 그런 이유로 클래스 인스턴스를 다시 내보내기하지 않습니다 (분명히?). 연결된 클래스 인스턴스에 액세스하려면 Control.Monad.Trans.Resource을 수동으로 가져와야합니다. 물론 다음 구문을 사용하여 수행 할 수 있습니다.

import Control.Monad.Trans.Resource() -- Only import instances 
+0

이 말이 맞기 때문에 이것을 올바르게 표시하고 있습니다. 그러나 내 코드는 새로운 가져 오기 라인을 추가 한 적이없는 것과 똑같은 오류를줍니다. 나는 경고를 생성하려고 시도한'() '도 삭제했다. 경고 없음 –

+0

파일을'ghci'로 로딩하고': i'를 사용하여'ResourceT'에 대한 범위 정보를 표시하려고 했습니까? – dflemstr

+0

예, 위 결과를 게시하겠습니다. –

4

내가 베팅 한 사람이라면 여러 버전의 라이브러리가 설치되어 있다고 말할 수 있습니다. 예를 들어, 버전 0.2와 0.3의 변압기가 있고 resourcet이 버전 0.2에 대해 작성되었다고 가정 해보십시오. import Control.Monad.Trans.Class (lift) 코드를 작성할 때 lift의 버전 0.3을 가져오고 있지만 관련 인스턴스가 없습니다.

가장 쉬운 방법은 코드를 캐 버리하는 것입니다. Cabal은 관련 라이브러리의 올바른 버전을 보유하고 있는지 확인합니다.

+0

고마워 마이클, 지금 당장 시험 중이 야. –

+0

BorisTest-0.1.0.0 구성 ... 빌딩 BorisTest-0.1.0.0 ... BorisTest-0.1.0.0에 대한 사전 처리 실행 파일 'Boris_Test'... client.hs : 12 : 8 : 'Control.Monad.Trans.Class'모듈을 찾을 수 없습니다. 숨겨진 패키지의 멤버입니다. '트랜스포머 -0.3.0.0 '입니다. .cabal 파일의 build-depends에'transformers '를 추가해야 할 수도 있습니다. 숨겨진 패키지'transformers-0.2.2.0 '의 멤버입니다. .cabal 파일의 build-depends에'transformers '를 추가해야 할 수도 있습니다. 검색된 파일 목록을 보려면 -v를 사용하십시오. –

+0

도덕적 인 이야기에서, 심각한 일이 발생할 때마다 음모를 사용하지 않아도됩니다. –