2013-10-16 2 views
3

생산자가 Producer ByteString IO()이고 파이프가 Pipe ByteString a IO() 인 경우 효과를 어떻게 작성합니까? 실행하면 IO a가됩니까?생산자와 파이프를 연결하여 결과 추출

여기에 최선을 시도입니다 :

그것은 다음과 같은 실패
{-# LANGUAGE ScopedTypeVariables #-} 
import Pipes 
import Data.ByteString 

run :: forall a. IO a 
run = runEffect $ 
    (undefined :: Producer ByteString IO()) >-> (undefined :: Pipe ByteString a IO()) 

: 일반적으로

Couldn't match type `Void' with `()' 
Expected type: IO a 
    Actual type: IO() 
In the expression: 
    runEffect 
    $ (undefined :: Producer ByteString IO()) 
    >-> (undefined :: Pipe ByteString a IO()) 
In an equation for `run': 
    run 
     = runEffect 
     $ (undefined :: Producer ByteString IO()) 
      >-> (undefined :: Pipe ByteString a IO()) 
+0

전체 소스 및 오류 메시지입니까? 그것은 매우 이상하게 보인다! 결국 그것은 Void와()를 통합하려고 시도하지만 Void는 예상되는 유형에 나타나지 않는다고 말합니다. –

+0

@DanielWagner'Void'가 나타납니다 ('Effect'타입 별명의 서명에 있음). (http://hackage.haskell.org/package/pipes-4.0.0/docs/Pipes-Core.html#t:Effect). 코드와 오류에 대해서는 업데이트를 참조하십시오. –

+1

문제의 해결책에 관계없이 GHC 본부에 오류가 얼마나 나쁜지 불평합니다! –

답변

4

, 당신은 실행할 수있는 Effect을 얻을 위해 ConsumerProducer를 구성 할 필요가 에 의해 runEffect. 여기에있는 내용이 아니지만 다행히 runEffect이 아닌 Proxy을 제거하는 방법이 더 있습니다.

우리가 가지고있는 것의 주식을 가지고이 구성은 Producer으로 끝납니다.

pipe :: Producer a IO() 
pipe = (undefined :: Producer ByteString IO()) >-> (undefined :: Pipe ByteString a IO()) 

Pipes.Prelude 모듈을 제거하기 위해 다양한 방법을 포함 Producers 아마

last :: Monad m => Producer a m() -> m (Maybe a) 

가장 일반적인 a의를 얻을 수있는 방법처럼 Pipes.Prelude.fold

fold :: Monad m => (x -> a -> x) -> x -> (x -> b) -> Producer a m() -> m b 

을 사용하는 것입니다 Pipes.Prelude.last 같은 runEffect 제외하면 Producers은 ~ Monad. 그것이 우리가 가진 것이기 때문에 위대한 일을 할 것입니다. 여기 slowHead 전체 Producer를 소비 (그리고 필요한 모든 효과 수행) 동안 Pipes.Prelude.head 수행 바로 첫 번째가된다는 사실을 주목할 필요가 있지만 우리가 Pipes.Prelude.head

slowHead = fold (\res a -> res <> First (Just a)) mempty getFirst 

을 구현할 수있는 방법입니다. 훨씬 게으르다!

+0

'head'를 사용하여 첫 번째 값을 가져올 수도 있습니다. 게으르며 첫 번째 요소를 얻을 수있을만큼만 프로듀서를 실행합니다. –

+1

좋아요! 고마워요! 따라서, 최종 결과는'run = Pipes.head $ (undefined :: Producer ByteString IO())> 형식의 서명을 가진'undefined :: Pipe ByteString a IO())'입니다. IO (어쩌면)' –

+0

@GabrielGonzalez'head'를 사용하는 솔루션은'run = runEffect $ (undefined :: Producer ByteString IO()) >>와 같은 효과가 있습니까? 파이프 ByteString a IO()) >> return Nothing)> -> (기다리고 >> = 반환. 그냥)'? –