When using mapM in interactive mode:
calling mapM putStrLn ["random","Text"]
the output is
random text [(),()]
however when i call the same function from a script and then run the script:
main = do
handle <- openFile "todo.txt" ReadMode
(tempName, tempHandle) <- openTempFile "." "temp"
contents <- hGetContents handle
let todoTasks = lines contents
numberedTasks = zipWith (\n line -> show n ++ "-" ++ line) [0..] todoTasks
putStrLn "These are your TO-DO items:"
mapM putStrLn numberedTasks -- <<<<<<<< HERE <<<<<<<<
putStrLn "Which one do you want to delete?"
numberString <- getLine
let number = read numberString
newTodoItems = delete (todoTasks !! number) todoTasks
hPutStr tempHandle $ unlines newTodoItems
hClose handle
hClose tempHandle
removeFile "todo.txt"
renameFile tempName "todo.txt"
with the line indicated I do not quite understand why I don't see
[()..()]
as the output when i run this script; I thought mapM
does not disregard the result
I thought
mapM
does not disregard the result
You thought correctly. It is your code, and not mapM
, that disregards the result; in particular,
do
mapM putStrLn numberedTasks
postamble
gets desugared to mapM putStrLn numberedTasks >> postamble
, and (>>)
disregards the result of its left argument.
I do not quite understand why i don't see
[()..()]
Actually, I suspect that what you don't understand is why you do see [(),()]
in GHCi. This is because, although GHCi behaves a little bit like being in a giant do
block, it is not quite. In particular it tries to show you partial results along the way. So GHCi is doing something special here: it is taking your action, running it, and additionally adding a print
statement for the result of the action.
If you would prefer not to see this printed out, there are several options; probably the best one is to replace mapM
with mapM_
; ghci has special code that avoids adding the print
statement when the result of the IO
action is ()
.