基于流的管道具有共同状态

时间:2017-05-29 11:51:57

标签: haskell haskell-pipes

我是 Streaming 库(https://hackage.haskell.org/package/streaming)中的Haskell初学者和新手,是最快和(我希望)最简单的流库。我试图制作下一个常见且受欢迎的模式":处理具有共同状态的流项目,请参见图:

   .--state-------+--state'--------+--state''-->
   |              |                |
[e0..eN] ==> [e0'...eN'] ==> [e0''..eN''] =====>

这个&#34;州&#34;将用于统计,错误等 - 通过整个工作流程。一些&#34;管道&#34;节点将迭代eN项(也将是列表/流),连接结果......如何使用流媒体库实现这一点?我的意思是每个&#34;节点&#34;应该有权访问流项目,但要访问&#34; global&#34;国家也是。节点也会执行IO操作!我尝试使用&#34; node&#34;作为状态(Stream&#39对中的第二个组件):stream是monad,因此do e <- stream将返回值之一绑定到e,但这看起来不太正确......

我的一个尝试是:

{-# LANGUAGE FlexibleContexts #-}
module Main where

import Control.Monad
import Control.Monad.Writer
import Data.Functor.Identity
import Streaming
import qualified Streaming.Prelude as S


type R = Writer [String] ()

gen :: S.Stream (S.Of Int) IO R
gen = do
  S.yield 1000
  S.yield 2000
  -- lift $ putStr "enter x: " -- ERROR: shown after input!!!
  x <- lift getLine
  let n = read x::Int
  S.yield n
  return $ do
    tell ["genErr1"]
    tell ["genErr2"]

proc1 :: S.Stream (S.Of Int) IO R -> S.Stream (S.Of Int) IO R
proc1 str = loop str
  where
    loop str = do
      e <- lift $ S.next str
      e' <- case e of
        Left err -> return err
        Right (e', str') -> (S.yield $ e' + 123) >> loop str'
      return $ do
        tell ["proc1Err1"]
        tell ["proc1Err2"]

main :: IO ()
main = do
  p <- S.mapM_ print $ proc1 gen
  putStr "p: " >> print p

我使用&#34;写&#34; -monad作为返回值(以保存我的日志/统计信息)......

所以,我希望处理来自proc1的{​​{1}}个流项目,并在最后为所有管道设置一个状态全局,其中&#34; genErr1&#34;,&# 34; genErr2&#34;,&#34; proc1Err1&#34;,&#34; proc1Err2&#34; (他们模拟过程流的项目时发生的错误)。怎么做到这一点?请问有人帮帮我吗?

PS。有趣的错误:输入后发生打印(在代码中标记为ERROR)。

0 个答案:

没有答案