[英]Haskell streaming - how to separate 1 stream into 2 after copy?
在haskell流中,有一個復制的例子
>>> (S.toList . mapped S.toList . chunksOf 5) $ (S.toList . mapped S.toList . chunksOf 3) $ S.copy $ each [1..10]
[[1,2,3,4,5],[6,7,8,9,10]] :> ([[1,2,3],[4,5,6],[7,8,9],[10]] :> ())
是否可以將其分成兩個“干凈”的流,以便它可以在結果下方打印?
>>>S.print stream1
[[1,2,3,4,5],[6,7,8,9,10]]
>>>S.print stream2
[[1,2,3],[4,5,6],[7,8,9],[10]]
請注意,上面的結果中不再有 ':>' 。 更一般地說,我不確定是否有函數可以“簡化”來自Stream (Of a) mr
m
或(Of a)
部分的嵌套流(或流的流)
f1::Stream (Of a) (Stream (Of b) m) r -> Stream (Of b) m r
f2::Stream (Of a) (Stream (Of b) m) r -> Stream (Of a) m r
f3::Stream (Stream (Of a) m) r -> Stream (Of a) m r
[更新]
這個問題的背景是我正在尋找多次重用底層流的慣用方法。 流是從數據庫中提取的,IO 可能很昂貴。 我還想獲得對中間流的引用,以便我可以更好地構建我的代碼。 一些模擬代碼:
my-stream-fn = do
original_stream <- pull_from_database
let (o1, s1) = calc_moving_average $ S.copy original_stream
(o2, s2) = calc_max $ S.copy o1
(o3, s3) = calc_min $ S.copy o2
S.print $ S.zipWith3 (\x y z-> (x, y, z)) s1 s2 s3
我希望 o1 o2 和 o3 與 original_stream 和 pull_from_database IO 操作完全相同,只在拉取 original_stream 時完成一次。
f1 = S.effects @(Stream (Of _) _)
:: Monad m
=> Stream (Of a) (Stream (Of b) m) r
-> Stream (Of b) r
f2 = hoist @(Stream (Of _)) S.effects
:: Monad m
=> Stream (Of a) (Stream (Of b) m) r
-> Stream (Of a) m r
(為清晰起見,類型變量已重命名,請參閱effects
文檔),並且f3
不進行種類檢查。
這感覺就像你試圖打敗流的地步。 您構建管道、源到接收器並運行它 - 關鍵是沒有(隱式)中間值累積。 您的問題有點松散,因此准確回答不同,但是如果您希望運行第一個流的所有效果,然后運行第二個流的所有效果,那么您必須願意存儲(表示)第二個流的計算直到第一個流完成影響 => 您已經積累了第二個流(因此沒有真正流式傳輸它)。 因此,為什么S.copy
是為交錯效果而設計的。 參見這個 github 問題。
我認為讓您感到困惑的部分原因是您使用的是純流,並且在沒有效果的情況下,限制的動機不那么明顯。 使用管道組件的標識符,而不是部分結果。 同樣在您的示例中,您應該組合折疊,例如。
import qualified Control.Foldl as L
import qualified Streaming.Prelude as S
myStreamFn =
let movingAvg n = {-# ... #-}
combinedAcc = (,,) <$> L.minimum <*> L.maximum <*> movingAvg 10
in S.print
$ L.purely S.fold combinedAcc
$ pullFromDatabase
您可能要考慮的另一個功能是S.store
,例如。
myStreamFn
= pullFromDatabase
& S.store S.maximum
& S.store (L.purely S.fold L.minimum)
& S.store movingAvg
& S.print
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.