나는 간단한 생산자/소비자 모델을 가지고 있는데, 소비자가 어떤 상태를 생산자에게 돌려주고 싶어한다고 말한다. 예를 들어, 하류로 흐르는 객체를 파일에 기록하고자하는 객체로, 상류 객체를 파일에 기록 된 위치 (예 : 오프셋)로 나타내는 토큰으로 보자.관용적 인 양방향 파이프 손실이없는 다운 스트림 상태의 파이프
이 두 과정은이 같은 간단한
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Pipes
import Pipes.Core
import Control.Monad.Trans.State
import Control.Monad
newtype Object = Obj Int
deriving (Show)
newtype ObjectId = ObjId Int
deriving (Show, Num)
writeObjects :: Proxy ObjectId Object() X IO r
writeObjects = evalStateT (forever go) (ObjId 0)
where go = do i <- get
obj <- lift $ request i
lift $ lift $ putStrLn $ "Wrote "++show obj
modify (+1)
produceObjects :: [Object] -> Proxy X() ObjectId Object IO()
produceObjects = go
where go [] = return()
go (obj:rest) = do
lift $ putStrLn $ "Producing "++show obj
objId <- respond obj
lift $ putStrLn $ "Object "++show obj++" has ID "++show objId
go rest
objects = [ Obj i | i <- [0..10] ]
, 나는 그것들을 구성하는 방법에 대한 추론 어려움의 공정한 조금 했어 수 있습니다 (
pipes-4.0
와) 같이 보일 수 있습니다. 이상적으로, 우리는 상류 초기
ObjId 0
을 보낸 데
request
에 차단하여 다음과 같은 컨트롤의 푸시 기반 흐름,
writeObjects
시작 싶어.produceObjects
는
writeObjects
객체를 기록하고, 그 상태를 증가 하류 제 객체Obj 0
를 보내고request
에 대기 이번에ObjId 0
produceObjects
와produceObjects
복귀 상류ObjId 1
respond
를 전송하는 단계로 진행 (2) 제 2의 대상과 함께,Obj 1
나의 최초의 시도는 (문제가있다 곳이 보인다) 푸시 기반 조성물
main = void $ run $ produceObjects objects >>~ const writeObjects
참고 다음 const
의 사용은 호환되지 않는 종류를 해결한다. 그러나이 경우, 우리는
Producing Obj 0
Wrote Obj 0
Object Obj 0 has ID ObjId 1
Producing Obj 1
...
끌어 오기 기반의 접근 방식,
main = void $ run $ const (produceObjects objects) +>> writeObjects
이 시간이 Obj 0
을 떨어 뜨리고, 비슷한 문제를 겪고, ObjId 0
먹을됩니다 것을 찾을 수 있습니다.
원하는 방식으로이 조각들을 어떻게 구성 할 수 있습니까?