Haskell: Inserting every line from a file into a list

前端 未结 2 1177
囚心锁ツ
囚心锁ツ 2020-12-31 10:22

I\'m currently working on project with Haskell, and have found myself some trouble. I\'m supposed to read and insert into a list each line in a \"dictionary.txt\" file, but

相关标签:
2条回答
  • 2020-12-31 11:05

    Unless this is for homework or something, there's no reason to use so much effort. Reuse is lazy!

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

    But as you seem to still be learning Haskell, it is important for you to understand what CesarB has written.

    0 讨论(0)
  • 2020-12-31 11:13

    In the line where the error happens, Haskell is expecting "IO a", but you are giving it a []. Simplifying things a lot, on a do block on the IO monad, every line is either:

    • Something which returns a value of the "IO a" type; the value of the "a" type within it is discarded (so the "a" is often "()")
    • A <- expression, which does the same thing but instead of discarding the value of the "a" type gives it the name to the left of the <-
    • A let, which does nothing more than give a name to a value

    In that do block, the "hGetLine inh" returns an "IO String", and the String within it is extracted and given the name inpStr. The next line, since it's neither a let or a <-, should have a type "IO a", which it doesn't (thus causing the compiler error). What you can do instead, since you already have the String, is a let:

    let list' = inpStr:list
    

    This creates a new list consisting of the String followed by the original list, and gives it the name of "list' ".

    Change the following line to use "list' " instead of "list" (thus passing it the new list). That line calls (recursively) mainloop, which will read one more line, call itself, and so on. After reading the whole file, it will return something with the "IO ()" type. This "IO ()" will be returned to the do block at loadNums. Congratulations, you just created a list with the lines read from the file, in reverse order (since you were appending to the head of the list), and then did nothing to it.

    If you want to do something to it, change the "return ()" to "return list"; the return will generate a value of type "IO [String]", with the list within it (return does nothing more than encapsulating the value), which you can extract at loadNums with the <- syntax.

    The rest is left as an exercise to the reader.

    0 讨论(0)
自定义标题
段落格式
字体
字号
代码语言
提交回复
热议问题