2015-04-30 3 views
0

Я пытаюсь создать функцию, которая создает источник, заданный некоторыми параметрами для подключения к URL-адресу, когда он правильно находится в монаде ResourceT. Я пытаюсь следующее:ResumableSource в http conduit приводит к ошибке «Невозможно построить бесконечный тип»

{-# LANGUAGE OverloadedStrings #-} 

import   Control.Monad.IO.Class  (liftIO) 
import   Data.Conduit     (($$), yield, unwrapResumable) 
import qualified Data.Conduit.List   as CL 
import   Network.HTTP.Conduit 
import   Network.HTTP.Types   (methodPost) 
import Control.Monad.Trans.Resource (runResourceT) 

runquery manager = do 
    initreq <- parseUrl "http://localhost/test" 
    let request = initreq{method=methodPost, requestBody=RequestBodyLBS "test"} 
    response <- http request manager 
    (httpsource, finalizer) <- unwrapResumable (responseBody response) 
    httpsource 
    finalizer 

main = do 
    manager <- newManager conduitManagerSettings 
    runResourceT $ (runquery manager $$ CL.mapM_ (liftIO . print)) 

Это не работает, я получаю «не может построить бесконечный тип» ошибки компилятора. Я могу return (httpsource,finalizer) (или просто весь ответ) и использовать его позже, но мне кажется странным. Каков правильный способ написания этого кода и почему я получаю ошибку бесконечного типа?

Без типа подписи, я получаю следующее сообщение об ошибке:

test.hs:17:3: 
    Occurs check: cannot construct the infinite type: 
     m 
     ~ 
     conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM 
     () ByteString m 
    Expected type: m() 
     Actual type: Source m ByteString 
    Relevant bindings include 
     finalizer :: m() (bound at test.hs:16:16) 
     httpsource :: Source m ByteString (bound at test.hs:16:4) 
     response :: Response 
        (conduit-1.2.4:Data.Conduit.Internal.Conduit.ResumableSource 
         m ByteString) 

Когда я добавить подпись, которая (я надеюсь, что должно быть):

runquery :: Manager -> Source (ResourceT IO) ByteString 

Я получаю сообщение об ошибке:

Couldn't match type ‘conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM 
         () ByteString (ResourceT IO)’ 
       with ‘ResourceT IO’ 
Expected type: conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM 
       () ByteString (ResourceT IO)() 
    Actual type: Source 
       (conduit-1.2.4:Data.Conduit.Internal.Conduit.ConduitM 
        () ByteString (ResourceT IO)) 
       ByteString 

Я, вероятно, делаю то, что не может быть сделано, но я не могу понять, где проблема.

+0

Вы можете сообщить об ошибке? сложно сказать без копирования и вставки и собственно компиляции кода в противном случае – Carsten

+0

Кстати: вы должны добавить подписи типа - даже если Haskell сделает все возможное, чтобы их вывести;) – Carsten

+1

ok - очевидная проблема в том, что вам нужно поднять 'finalizer' перед использованием - но почему вы даже используете 'http' вместо' httpLbs' или даже 'simpleHttp'? – Carsten

ответ

0

unwrapResumable, http и finalizer необходимо запустить в resourceT, кажется, работают только в контексте MonadResource (например, resourceT), поэтому вам нужно поднять их в него.

 Смежные вопросы

  • Нет связанных вопросов^_^