簡體   English   中英

Haskell 流媒體 - 如何在復制后將 1 個流分成 2 個?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM