天天看點

泛函程式設計(36)-泛函Stream IO:IO資料源-IO Source & Sink

 上期我們讨論了io處理過程:process[i,o]。我們說process就像電視信号盒子一樣有輸入端和輸出端兩頭。process之間可以用一個process的輸出端與另一個process的輸入端連接配接起來形成一串具備多項資料處理功能的完整io過程。但合成的io過程兩頭輸入端則需要接到一個資料源,而另外一端則可能會接到一個資料接收裝置如檔案、顯示屏等。我們在這篇簡單地先介紹一下io資料源source和io資料接收端sink。

我們先用一個獨立的資料類型來代表資料源source進行簡單的示範說明,這個類型與process類型沒有任何關系:

從以上trait可以看到:source的工作原理就是把一個process的輸入黏貼到source的輸出端。我們可以用這個 |> 把一串process粘到source的輸出,如:src.proc1.proc2.proc3。不過我們得先把proc1,proc2,proc3定義成source元件函數,因為source是一個完全獨立的類型。

我們再來看看一個source特殊案例:

這是個隻讀的資料源。我們看到所有的動作都被包嵌在io類型裡,這樣可以把副作用的産生延後到一些source interpreter來運算。這裡我們隻要用最簡單的io來說明就可以了:

這個io類型我們在前面的讨論裡曾經練習過。

現在我們來看看一個檔案讀取的resourcer例子:

現在我們可以這樣寫一段程式了:

噢,記住把count和exists放到source trait裡:

上面的表達式可以說還隻是io過程的描述。實際副作用産生是在interpreter裡:

注意:無論讀取完成或中途失敗退出都會導緻現場清理以防止資源漏出。可以推斷這個interpreter還是很安全的。

與source同樣,我們還是用一個獨立的類型sink來代表資料接收端進行簡單說明:

這和source trait及其相似。注意和process連接配接是反向的:由p指向sink。

同樣,一個隻寫的資源執行個體如下:

這個也和resourcer相似。還是與process連接配接方式是反方向的:由p到trans。

以下是一個向檔案寫入的sink元件:

在學習過程中發現,獨立于process類型的source,sink類型使io算法的表達式類型的內建很困難。這也限制了元件的功能。我們無法實作泛函程式設計簡潔高雅的表達形式。在下面的讨論中我們會集中精力分析具備資料源功能的process,希望在表達方式上能有所進步。

繼續閱讀