Haskell read lines of file
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.
LeonS
Updated on July 09, 2022Comments
-
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 aString
DataType, why isn't it? -
Gabriella Gonzalez almost 12 yearsAdditionally, compare this to the type of getArgs and readFile, for completeness.
-
kjh over 8 yearsHow does this solution work? You can't pass
content
tolines
because the type oflines
isString -> [String]
and the type ofcontent
isIO String
-
Daniel Fischer over 8 years@kjh No,
content
is aString
. The type ofreadFile (args !! 0)
isIO String
, and we bindcontent
to the "result" of thatIO
-action. The constructdo { a <- action; stuff; }
desugars intoaction >>= \a -> stuff
, ifaction
has typeIO t
, thena
has typet
. -
kjh over 8 yearsI see now. Thank you for clarifying