我认为我开始了解Coroutine的制作人和消费者,但我最难以有用的方式将消费者和产品放在一起。如果我有APIEvent
的生产者......
type ID = String
data APIEvent
= Connecting
| Fail String
| Success String
derive instance gAPIEvent :: Generic APIEvent
instance showPeerEvent :: Show APIEvent where show = gShow
getID :: Producer APIEvent (Aff (avar :: AVAR, console :: CONSOLE, random :: RANDOM)) (Maybe ID)
getID = produceAff (\emit -> do
i <- liftEff $ randomInt 0 10
if i < 9
then do
-- If producer was called with `loop`, the
-- producer will restart.
emit $ Left $ Fail "Failure to get id."
emit $ Right Nothing
else do
emit $ Left $ Success "id"
emit $ Right $ Just "id"
)
如何将其连接到两个执行系统日志记录和基本操作的使用者 输出,例如
logFailures :: Consumer APIEvent (Aff (avar :: AVAR, console :: CONSOLE, random :: RANDOM)) ID
logFailures = forever $ do
event <- await
lift $ do
case event of
(Fail message) -> log $ "LOG: " <> message
showOutput :: Consumer APIEvent (Aff (avar :: AVAR, console :: CONSOLE, random :: RANDOM)) ID
showOutput = forever $ do
event <- await
lift $ do
log $ "STDOUT: " <> (show event)
我已尝试使用joinConsumers
,但这会创建一个消费者
(Tuple APIEvent APIEvent
)而不仅仅是APIEvent
,所以那么
它没有打字检查。
main = launchAff $ do
v <- runProcess $
(joinConsumers logFailures showOutput)
`pullFrom` (loop getPeerID)
log $ "Process result: " <> (show v)
编辑:
这就是我最终的目标。
main = launchAff $ do
v <- runProcess $
transformConsumer
(forever $ transform (\i -> Tuple i i))
(joinConsumers logFailures showOutput)
`pullFrom` (loop getID)
log $ "Process result: " <> (show v)
...输出
LOG: Failure to get id.
STDOUT: Test.SO.Fail "Failure to get id."
LOG: Failure to get id.
STDOUT: Test.SO.Fail "Failure to get id."
STDOUT: Test.SO.Success "id"
Process result: "id"
答案 0 :(得分:4)
正如您所注意到的,您可以使用joinConsumers
将两个Consumer
合并到Consumer
个Tuple
中。现在,您只需要一种方法将Consumer
Tuple a a
更改为常规Consumer
a
。
您可以使用transformConsumer
功能执行此操作,该功能使用Consumer
转换Transformer
:
transformConsumer
:: forall i o f m a
. (MonadRec m, Parallel f m)
=> Transformer i o m a
-> Consumer o m a
-> Consumer i m a
但是如何在那里创建Transformer
?好吧,您可以使用transform
函数从常规函数创建一个函数:
transform
:: forall m i o
. Monad m
=> (i -> o)
-> Transformer i o m Unit
您需要的功能类型为a -> Tuple a a
,因此\a -> Tuple a a
可以完成此任务。