我想在哈斯克爾的一個小實驗,想知道是否有可能利用懶惰來處理IO。我想編寫一個函數,它接受一個String(一個Chars列表),併產生一個字符串,懶洋洋地。然後,我希望能夠懶惰地從IO中緩慢地提供它的字符,因此每個字符都會在可用時立即進行處理,並且會在需要的字符可用時生成輸出。但是,我不太確定是否/如何從IO單元內的輸入中生成一個懶惰列表。Haskell中的「惰性IO」?
回答
Haskell中的常規字符串IO很懶。所以你的例子應該是開箱即用。
下面是一個例子,使用「交互」功能,它適用的功能字符的懶惰流:
interact :: (String -> String) -> IO()
讓我們從輸入流中過濾出字母e,懶惰地(即,運行在不斷的空間):
main = interact $ filter (/= 'e')
你也可以,如果你喜歡用getContents和putStr。他們都很懶。
運行它從字典中篩選字母「E」:
$ ghc -O2 --make A.hs
$ ./A +RTS -s < /usr/share/dict/words
...
2 MB total memory in use (0 MB lost due to fragmentation)
...
,所以我們看到它在一個恆定2M足跡跑了。
你也可以在命令行看到這個效果。在shell/Terminal /運行Don的'A'程序,無論您的操作系統使用什麼,並直接輸入文本。假設它是行緩衝的,當你在每行之後按回車時,即使程序看起來只是對「過濾器」進行一次「調用」,你仍會立即看到過濾後的文本。 – Nefrubyr 2010-02-19 11:49:10
unsafeInterleaveIO :: IO a -> IO a
unsafeInterleaveIO
阿洛斯IO
計算被推遲懶洋洋地。當通過IO a
類型的值時,IO
將僅在要求值a
時執行。這用於實現惰性文件讀取,請參閱System.IO.hGetContents
。
例如,main = getContents >>= return . map Data.Char.toUpper >>= putStr
是懶惰的;當你向標準輸入提供字符時,你會在標準輸出中獲得字符。
(這是一樣的書寫main = interact $ map Data.Char.toUpper
,爲行蹤詭祕的回答。)
做懶IO的最簡單的方法涉及的功能,如interact
,readFile
,hGetContents
,而這樣,作爲穿上說;在書中Real World Haskell中有更多關於這些的討論,您可能會覺得有用。如果內存服務於我,所有這些功能最終都會使用ephemient提到的unsafeInterleaveIO
來實現,所以您也可以按照自己的意願構建自己的函數。
另一方面,請注意unsafeInterleaveIO
正如它在錫罐上所說的那樣:不安全的IO可能是明智的。使用它 - 或基於它的功能 - breaks purity and referential transparency。這允許顯然是純粹的功能(即,不返回IO
動作)在評估時影響外部世界,從相同的參數產生不同的結果,以及所有其他不愉快的事情。在實踐中,使用unsafeInterleaveIO
的最明智的方式不會造成問題,而簡單的錯誤通常會導致明顯且容易診斷的錯誤,但是您失去了一些很好的保證。
當然有其他選擇;你可以在Hackage上找到提供受限制的,safer lazy IO或conceptually different approaches的各種圖書館。但是,鑑於問題在實際使用中很少出現,我認爲大多數人傾向於堅持內置的,技術上不安全的功能。
- 1. Haskell:隱藏IO惰性故障
- 2. 困惑:Haskell IO懶惰
- 3. Haskell:原子IO包裝/懶惰?
- 4. Haskell惰性卸載
- 5. 強制對惰性IO進行評估
- 6. Haskell中的懶惰模式
- 7. Haskell中IO的映射
- 8. 與haskell中的IO映射?
- 9. Haskell中的IO問題
- 10. Haskell中的IO不可見
- 11. Haskell惰性打開和關閉文件
- 12. Haskell的IO遞歸
- 13. Haskell的IO例如
- 14. Haskell monadic IO
- 15. Haskell ReplicateM IO
- 16. Haskell基本IO
- 17. Haskell,IO,monads,quickcheck
- 18. IO monad中的懶惰計算
- 19. 懶惰的本質。 Haskell
- 20. 觀察Haskell的懶惰
- 21. Haskell IO與數字
- 22. 遞歸IO在Haskell
- 23. haskell io流內存
- 24. Haskell比較IO UTCTime
- 25. haskell網絡io hgetline
- 26. 惰性IO +並行性:將圖像轉換爲灰度
- 27. Haskell中的懶惰前向參考
- 28. 幫助Haskell的IO輸入
- 29. Haskell內部的IO實現
- 30. Haskell的函數定義IO
請澄清:你需要一個接受一個字符串和「產生」一個字符串---「產生」=「返回」,「輸出到文件句柄」的函數,或者是什麼?然後你想「懶惰地從IO中提取字符」---這是什麼意思? – dave4420 2010-02-18 16:42:25