簡體   English   中英

流媒體庫 Stream fmr 中函子背后的直覺

[英]Intuition behind the functor in Stream f m r of the streaming library

流媒體庫中Stream的簡化(無效)定義如下所示:

data Stream f = Step (f (Stream f))
              | Return

我想了解引入這個函子f的動機是什么。

一個典型的這樣的fOf a ,其中Of定義為

data Of a b = !a :> b
    deriving Functor

當我在Stream的定義中將f讀作Of a時,這種說法是有道理的, Of ab類似於a后跟更多可從b獲得的東西。 通過這種解釋, Stream 定義中的 f ( Stream f (Stream f)讀起來類似於Of a (Stream (Of a)) 但在這種情況下,一個更簡單的版本應該是

data Stream a = Step a (Stream a)
              | Return

我很難理解為什么使用這個仿函數f的泛化。 在介紹中,作者說Stream

...可用於流式傳輸以任何函子f為特征的連續的不同步驟

通用類型Stream fmr表示一系列步驟……其形狀由“仿函數”參數f確定。

但是在Streaming.Prelude中,我能找到的唯一仿函數是Or aStream (Of a) mIdentity 第一個生成a流,第二個生成流,第三個實現'erasure'

我真的不明白。 我可以實現所有這些事情,即a的簡單流、流的流和擦除,而無需在Stream中使用這個f

這個仿函數f做了哪些其他事情做不到的事情?

streaming分組函數的一個關鍵特性是它們不會強制您在任何時候將整個組保存在內存中。 他們以“流式”方式進行分組。 一旦檢測到新組的開始,您就可以開始“下游”處理該組。

例如,想象一個類似lines:: Stream (Of Text) IO r -> Stream (Stream (Of Text) IO) IO r 只要該函數在流中檢測到換行符,就會啟動一個新組,即使新行的末尾尚未具體化

Stream (Stream (Of Text ) IO) IO r類型的優點是,要到達當前行之后的行,我們必須完全消耗當前行。 這是因為“流的其余部分”位於仿函數參數的結果值中。 Stream只有在用完后才會放棄它們的結果。

Stream (Of (Stream (Of a) IO ()) IO ()這樣的類型不會強制我們在移動到下一行之前耗盡當前行。我們可以簡單地忽略在外部Stream Stream但是那個“下一行”可能還不存在,因為我們還沒有真正讀過之前的內容,也許這個方案可以以某種方式工作。但是語義會不太清楚並且需要用戶更多的知識。


mapped這樣的函數讓我們使用定義為“上游”的“下游”組。 例如,此代碼從stdin讀取字符串,其中字符串“-”是組分隔符。 下游代碼將字符串解析為Int並在遇到5時顯示一條消息。 請注意,消息是在組關閉上游之前顯示的。

    import Streaming
    import qualified Streaming.Prelude as S

    example :: Stream (Of ()) IO () 
    example = 
        let upstream :: Stream (Stream (Of String) IO) IO ()
            upstream = S.breaks (=="-") S.stdinLn
            downstream :: Stream (Stream (Of String) IO) IO () 
                       -> Stream (Of ()) IO ()
            downstream = S.mapped handleGroup
            handleGroup :: Stream (Of String) IO r ->
                           IO (Of () r)
            handleGroup stream = do
                print "group began" 
                r <- S.effects
                   . S.chain (\_ -> putStrLn "found!") 
                   . S.filter (==5) 
                   . S.map (read @Int) 
                   $ stream 
                print "group ended"
                return (() :> r)
         in downstream upstream

    main :: IO ()
    main = S.effects example

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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