[英]Haskell: why does this code fail?
當我嘗試運行此代碼時......
module Main where
import qualified Data.Text.Lazy.IO as LTIO
import qualified Data.Text.Lazy as LT
import System.IO (IOMode(..), withFile)
getFirstLine :: FilePath -> IO String
getFirstLine path =
withFile path ReadMode (\f -> do
contents <- LTIO.hGetContents f
return ("-- "++(LT.unpack . head $ LT.lines contents)++" --"))
main::IO()
main = do
firstLine <- getFirstLine "/tmp/foo.csv"
print firstLine
我明白了
"-- *** Exception: Prelude.head: empty list
...我希望它打印“/tmp/foo.csv”的第一行。 你能解釋一下原因嗎? 最后,我試圖弄清楚如何從文件輸入創建一個懶惰的文本列表。
正如Daniel Lyons在評論中提到的那樣,這是由於IO和懶惰相互作用。
想象一下,如果你願意:
withFile
打開文件,文件句柄f
。 f
內容的Thunk。 withFile
關閉文件。 HaskellWiki /維護懶惰頁面上提到了此陷阱。
要修復,您可以讀取withFile
的整個文件內容(可能通過強制使用seq
)或懶惰地關閉文件而不是使用withFile
。
我認為是這樣的: withFile
在執行函數后關閉文件。 hGetContents
懶惰地讀取內容(懶惰的IO),當它需要讀取內容時,文件被關閉。
而不是使用withFile
,嘗試使用openFile
,而不是關閉它。 hGetContents
將在文件hGetContents
后將文件置於半封閉狀態。 或者更好,只需使用readFile
直接讀取內容
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.