3 回答

TA貢獻1111條經驗 獲得超0個贊
Logan指向的論文很棒,但是有點困難。(只問我的學生。)“流融合的工作原理”也很重要,而“流融合是什么以及如何使用它”只是很小一部分。
流融合解決的問題是,編寫的功能代碼經常分配中間列表,例如,為了創建節點號的無限列表,您可能會編寫
nodenames = map ("n"++) $ map show [1..]
天真的代碼會分配一個無限的整數列表[1, 2, 3, ...],一個無限的字符串列表["1", "2", "3", ...],最后是一個無限的名稱列表["n1", "n2", "n3", ...]。分配太多了。
流融合的作用是將類似的定義nodenames轉換為使用遞歸函數的定義,該遞歸函數僅分配結果所需的內容。通常,消除中間列表的分配稱為砍伐森林。
要使用流融合,您需要編寫非遞歸列表函數,這些函數使用GHC票務915(map,foldr等)中描述的流融合庫中的函數,而不是顯式遞歸。該庫包含所有Prelude函數的新版本,這些函數已被重寫以利用流融合。顯然,這些內容將使它成為下一個GHC版本(6.12)的組成部分,但不在當前的穩定版本(6.10)中。如果您想使用庫,Porges的回答中有一個很好的簡單解釋。
如果您實際上想要解釋流融合的工作原理,請提出另一個問題-但這要困難得多。

TA貢獻1877條經驗 獲得超6個贊
據我所知,與諾曼所說的相反,流融合目前不是在GHC的基礎上實現的(即,您不能僅使用Prelude函數)。有關更多信息,請參見GHC票務915。
要使用流融合,您需要安裝流融合庫,導入Data.List.Stream(也可以導入Control.Monad.Stream),并且僅使用該模塊中的函數而不是Prelude函數。這意味著導入Prelude隱藏所有默認列表函數,而不使用[x..y]構造或列表推導。

TA貢獻1810條經驗 獲得超5個贊
是不是正確的,當GHC在6.12中默認使用這些新函數時,它們也將以非遞歸方式實現[x..y]并列出理解嗎?因為它們不是正確的行,唯一的原因是它們是內部的,不是真正用Haskell編寫的,而是出于速度和/或因為您無法重新定義該語法而更像關鍵字。
- 3 回答
- 0 關注
- 506 瀏覽
添加回答
舉報