haskell 中 MapM 的结果?

result of MapM in haskell?

在交互模式下使用 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不理会结果

I thought mapM does not disregard the result

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

do
    mapM putStrLn numberedTasks
    postamble

脱糖为 mapM putStrLn numberedTasks >> postamble,并且 (>>) 忽略其左侧参数的结果。

I do not quite understand why i don't see [()..()]

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

如果您不想看到这个打印出来,有几个选项;可能最好的方法是将 mapM 替换为 mapM_; ghci 有特殊的代码,当 IO 操作的结果是 ().

时避免添加 print 语句