Skillga
Skillga

Reputation: 13

Having problems with writeFile in Haskell IO

First of all im new around here and thanks for helping out.

The problem is basically i am being unable to write into a file by using writeFile in Haskell. Code:

main = do
    putStrLn "Input file: "
    ifile <- getLine
    result <- readFile ifile >>= print . emit . compile . calc . lexer
    print result

This is what i currently have and i know that the function emit is returning correctly. Aditional info on functions im using:

    emit :: (Int, Int, [Stuff]) -> String
    compile :: C -> (Int, Int, [Stuff])

I can get the result printed with the above code and it returns along lines of:

"stuff i want"
()

I'm finding the () funny but i figure i can remove it from the file afterwards.

When i try to use the writeFile in the following manner:

writeFile "file.txt" results

It gives me the following error:

    Couldn't match type `()' with `[Char]'
    Expected type: String
      Actual type: ()
    In the second argument of `writeFile', namely `result'
    In a stmt of a 'do' block: writeFile "result.txt" result
    In the expression:
      do { putStrLn "Input file: ";
        ifile <- getLine;
        result <- readFile ifile >>= print . emit . compile . calc . lexer;
        writeFile "result.txt" result }

Anyone knows how i can fix this? Thanks in advance!

Upvotes: 1

Views: 371

Answers (1)

Cactus
Cactus

Reputation: 27636

The "funny" () is actually the key to understanding this. The output () is emitted by the last line of main, print result, because result has type ().

Why? Because it is bound to the result of print . emit . compile . calc . lexer =<< readFile ifile; or, simplified, to the result of print . f =<< readFile ifile for some pure compiler pipeline f. The result of this is the result of the print, which is just () (print doesn't return anything useful, it just prints its argument to stdout as an effect).

What you want to do is to not print anything then and there, and just bind the actual result of running your compile pipeline; i.e. something like

result <- emit . compile . calc . lexer <$> readFile ifile

Upvotes: 1

Related Questions