New to Haskell and wrestling with a problem. I know why my code doesn't work, but I cannot figure out the solution.
The intention is for the user to provide a file name either via argument or, if none provided, prompt the user to enter the data. A message with the file name is printed to the screen and the file is processed.
import System.Environment
main = do
args <- getArgs
let file = if null args
then do putStr "File: " ; getLine
else head args
putStr "processing"
putStrLn file
writeFile file "some very nice text"
The code is wrong, of course, but demonstrates the logic I've been wrestling with. Neither Happy Learn Haskell nor Learn you Haskell could put me over the hump. The closest thread I could find was this one. Many thanks for assistance.
Let us analyze the type of file:
let file = if null args
then do putStr "File: " ; getLine
else head args
Here the if-then-else statement has as condition null args, which is indeed a Bool, so we are safe. But the the then part has as type IO String. So Haskell reasons that args should be an [IO String], but it is not: it is a list of Strings, so [String].
Later another problem pops up: you use file as a String, but it is not: it is still an IO String.
There are a few ways to fix it. Probably the minimal change is to use pure to wrap the head args back into an IO, and use replace the let clause with a <- statement:
import System.Environment
main = do
args <- getArgs
file <- if null args
then do putStr "File: " ; getLine
else pure (head args)
putStr "processing "
putStrLn file
writeFile file "some very nice text"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With