Home > Net >  String to IO String (conditional mapM)
String to IO String (conditional mapM)

Time:07-27

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.

  • Related