I'm working on my first Haskell tool (yay!) and I can't seem to find a solution to this problem. Most posts discuss converting a String
to IO String
, but I actually need to do the inverse, since I conditionally use readFile
inside mapM
.
I'm sure there are better ways to do this, but here's what I've got so far. This parses a source file (unrelated language) and replaces #include
statements with the actual contents of the include file.
replaceInclude :: String -> IO String
replaceInclude contents = do
f_lines <- mapM
(\l ->
if (isInfixOf "#include" l)
then readFile (parseIncludePath l)
else l -- !! This is the problem line !!
)
(lines contents)
return (unlines f_lines)
As noted in comments, the problem line is the else
statement, which returns a String
, but mapM
expects an IO String
.
Any help would be appreciated, I believe I have to rewire my brain to do this the "haskell way" :)
Compile error :
* Couldn't match type `[]' with `IO'
Expected type: IO String
Actual type: [Char]
CodePudding user response:
OMG this was so simple, the solution is else return l
.
For posterity and other beginners:
In Haskell, the return
function creates an IO
tagged type. It is such because reasons. This documentation in A Gentle Introduction to Haskell is helpful and clear.