当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《Haskell:将文件中的每一行插入到列表中》经验,为你挑选了2个好方法。

我目前正在与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字符串,我不知道如何处理以获得一个正确的字符串,我可以在我的列表中插入.我不知道如何解决这个问题,或者问题究竟是什么,但如果有人知道如何正确地将文件中的每一行都放入列表中,我会很感激.

提前致谢!



1> ephemient..:

除非这是作业或其他东西,否则没有理由使用这么多的努力.重用是懒惰的!

getLines = liftM lines . readFile

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

但是,由于您似乎仍在学习Haskell,因此了解CesarB编写的内容非常重要.


提及`readFile`的+1.摆脱打开文件/读取行/检测EOF /关闭文件的命令性思维是非常有帮助的,让`readFile`,`getContents`和`interact`等函数为你处理混乱.

2> 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中提取该值.

其余部分留给读者练习.

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有