在haskell中MapM的结果?

时间:2016-08-01 21:25:59

标签: haskell io ghci

在交互模式下使用mapM时: 致电mapM putStrLn ["random","Text"] 输出是

random
text
[(),()]

然而,当我从脚本调用相同的函数然后运行脚本时:

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" 

指示线我不太明白为什么我不明白 [()..()]作为运行此脚本时的输出;我认为mapM不会忽视结果

1 个答案:

答案 0 :(得分:5)

  

我认为mapM不会忽视结果

你想的没错。忽视结果是你的代码,而不是mapM;特别是,

do
    mapM putStrLn numberedTasks
    postamble

被置于mapM putStrLn numberedTasks >> postamble,而(>>)无视其左参数的结果。

  

我不太明白为什么我不看[()..()]

实际上,我怀疑你不明白为什么你 在GHCi中看到[(),()]。这是因为,虽然GHCi有点像在一个巨大的do块中,但它并不完全。特别是它试图在整个过程中向您展示部分结果。所以GHCi在这里做了一些特别的事情:它正在采取行动,运行它,并且另外为行动的结果添加print声明。

如果您不希望看到这个打印出来,有几种选择;可能最好的方法是用mapM替换mapM_; ghci有一些特殊代码,可以避免在print操作的结果为IO时添加()语句。