簡體   English   中英

Haskell:為什么這段代碼失敗了?

[英]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關閉文件。
  • Thunk被評估。 已關閉的文件中沒有內容。

HaskellWiki /維護懶惰頁面上提到了此陷阱。

要修復,您可以讀取withFile的整個文件內容(可能通過強制使用seq )或懶惰地關閉文件而不是使用withFile

我認為是這樣的: withFile在執行函數后關閉文件。 hGetContents懶惰地讀取內容(懶惰的IO),當它需要讀取內容時,文件被關閉。

而不是使用withFile ,嘗試使用openFile ,而不是關閉它。 hGetContents將在文件hGetContents后將文件置於半封閉狀態。 或者更好,只需使用readFile直接讀取內容

暫無
暫無

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

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