Haskell流-如何将原始流与结果流合并
使用,我可以很容易地对一个流进行分组,并对每个组进行求和Haskell流-如何将原始流与结果流合并,haskell,streaming,haskell-streaming,Haskell,Streaming,Haskell Streaming,使用,我可以很容易地对一个流进行分组,并对每个组进行求和 >>> S.print $ mapped S.toList $ S.groupBy (\ x y -> x*y>0) $ each [-1,-2,3,4,5,-6] [-1,-2] [3,4,5] [-6] >>> S.print $S.map sum $ mapped S.toList $ S.groupBy (\ x y -> x*y>0) $ each [-1,-2,3,
>>> S.print $ mapped S.toList $ S.groupBy (\ x y -> x*y>0) $ each [-1,-2,3,4,5,-6]
[-1,-2]
[3,4,5]
[-6]
>>> S.print $S.map sum $ mapped S.toList $ S.groupBy (\ x y -> x*y>0) $ each [-1,-2,3,4,5,-6]
-3
12
-6
如何让函数myfn
以顺序敏感的方式生成上述两个流的合并流?也就是说,我希望有一个结果流
>>> myfn $ each [-1,-2,3,4,5,-6]
-1:> -2:> -3:> 3:> 4:> 5:> 12:> -6:> -6:> ()
解决方案包括将
的函数参数映射为
,一次累积列表并计算总和
我想这可以用软件来完成,但我发现流媒体接收器更容易使用。他们的Applicative
实例让我们可以从简单的实例构建复合Fold
s:
foo :: Monad m
=> (Int -> Int -> Bool)
-> Stream (Of Int) m ()
-> Stream (Of Int) m ()
foo p =
flip S.for (\(xs,total) -> S.each xs *> S.yield total)
. mapped (L.purely S.fold $ (,) <$> L.list <*> L.sum)
. S.groupBy p
编辑:想想看,以前的解决方案有缺陷。我们只对流式结果感兴趣,但在将其发送到下游之前,我们使用S.toList
或L.list
在内存中累积每个组。但是如果一个组恰好比机器中的可用内存大呢
以下是一个完美的流式解决方案,它与每个组的大小无关:
foo :: Monad m
=> (Int -> Int -> Bool)
-> Stream (Of Int) m ()
-> Stream (Of Int) m ()
foo p =
concats
. S.maps (S.store (\s -> do (total :> r) <- L.purely S.fold L.sum s
S.yield total
return r))
. S.groupBy p
foo::Monad m
=>(整数->整数->布尔)
->流(整数)m()
->流(整数)m()
foop=
海螺
. S.maps(S.store(\S->do(总计:>r)
foo :: Monad m
=> (Int -> Int -> Bool)
-> Stream (Of Int) m ()
-> Stream (Of Int) m ()
foo p =
concats
. S.maps (S.store (\s -> do (total :> r) <- L.purely S.fold L.sum s
S.yield total
return r))
. S.groupBy p