Haskell read lines of file

29,722

I thought by binding the result of readFile to content it will be a String DataType, why isn't it?

It is a String indeed, that's not what the compiler complains about. Let's look at the code:

main = do
   args <- getArgs
   content <- readFile (args !! 0)

Now content is, as desired, a plain String. And then lines content is a [String]. But you're using the monadic binding in the next line

   linesOfFiles <- lines content

in an IO () do-block. So the compiler expects an expression of type IO something on the right hand side of the <-, but it finds a [String].

Since the computation lines content doesn't involve any IO, you should bind its result with a let binding instead of the monadic binding,

   let linesOfFiles = lines content

is the line you need there.

Share:
29,722
LeonS
Author by

LeonS

Updated on July 09, 2022

Comments

  • LeonS
    LeonS almost 2 years

    I want to read a whole file into a string and then use the function lines to get the lines of the string. I'm trying to do it with these lines of code:

    main = do
       args <- getArgs
       content <- readFile (args !! 0)
       linesOfFiles <- lines content
    

    But I'm getting the following error by compiling ad it fails:

    Couldn't match expected type `IO t0' with actual type `[String]'
    In the return type of a call of `lines'
    In a stmt of a 'do' block: linesOfFiles <- lines content
    

    I thought by binding the result of readFile to content it will be a String DataType, why isn't it?

  • Gabriella Gonzalez
    Gabriella Gonzalez almost 12 years
    Additionally, compare this to the type of getArgs and readFile, for completeness.
  • kjh
    kjh over 8 years
    How does this solution work? You can't pass content to lines because the type of lines is String -> [String] and the type of content is IO String
  • Daniel Fischer
    Daniel Fischer over 8 years
    @kjh No, content is a String. The type of readFile (args !! 0) is IO String, and we bind content to the "result" of that IO-action. The construct do { a <- action; stuff; } desugars into action >>= \a -> stuff, if action has type IO t, then a has type t.
  • kjh
    kjh over 8 years
    I see now. Thank you for clarifying