簡體   English   中英

Haskell:將文件中的每一行插入到列表中

[英]Haskell: Inserting every line from a file into a list

我目前正在與Haskell合作,並發現自己遇到了一些麻煩。 我應該在“dictionary.txt”文件中讀取並插入列表中的每一行,但我似乎無法這樣做。 我有這個代碼:

main = do
    let list = []
    loadNums "dictionary.txt" list

loadNums location list = do
    inh <- openFile location ReadMode
    mainloop inh list
    hClose inh

mainloop inh list = do 
    ineof <- hIsEOF inh
    if ineof
        then return ()
        else do 
            inpStr <- hGetLine inh
            inpStr:list
            mainloop inh list

它應該得到每一行(我知道它確實得到每一行,因為用“putStrLn inpStr”替換“inpStr:list”正常工作,顯示所有行),並將其插入列表但我得到以下錯誤:

Couldn't match expected type `IO' against inferred type `[]'

可能是因為hGetLine不是一個字符串,而是一個IO字符串,我不知道如何處理以獲得一個正確的字符串,我可以在我的列表中插入。 我不知道如何解決這個問題,或者問題究竟是什么,但如果有人知道如何正確地將文件中的每一行都放入列表中,我會很感激。

提前致謝!

除非這是作業或其他東西,否則沒有理由使用這么多的努力。 重用是懶惰的!

getLines = liftM lines . readFile

main = do
    list <- getLines "dictionary.txt"
    mapM_ putStrLn list

但是,由於您似乎仍在學習Haskell,因此了解CesarB編寫的內容非常重要。

在發生錯誤的行中,Haskell期望“IO a”,但是你給它一個[]。 在IO monad的do塊上簡化了很多事情,每一行都是:

  • 返回“IO a”類型值的東西; 其中“a”類型的值被丟棄(因此“a”通常是“()”)
  • 一個< - 表達式,它執行相同的操作,但不是丟棄“a”類型的值,而是給出了< - 左側的名稱 -
  • 一個let,它只是給一個值賦一個名字

在那個do塊中,“hGetLine inh”返回一個“IO String”,並且提取其中的String並給出名稱inpStr。 下一行,因為它既不是let也不是< - ,應該有一個類型“IO a”,它不會(因此導致編譯器錯誤)。 你可以做什么,因為你已經有了String,是一個let:

let list' = inpStr:list

這將創建一個新的列表,其中包含String后跟原始列表,並為其指定名稱“list”。

更改以下行以使用“list”而不是“list”(從而將新列表傳遞給它)。 該行調用(遞歸)mainloop,它將讀取另一行,調用自身,依此類推。 讀完整個文件后,它將返回“IO()”類型的內容。 這個“IO()”將返回到loadNums的do塊。 恭喜你,你剛剛創建了一個列表,其中包含從文件中讀取的行,順序相反(因為你附加到列表的頭部),然后對它沒有任何作用。

如果你想對它做點什么,把“return()”改為“return list”; return將生成一個類型為“IO [String]”的值,其中包含列表(return只會封裝該值),您可以使用< - syntax在loadNums中提取該值。

其余部分留給讀者練習。

暫無
暫無

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

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