Search code examples
haskellioghci

result of MapM in haskell?


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


Solution

  • 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 ().