理解`sequence_`

Understanding `sequence_`

All About Monads 说明 sequence_:

The sequence_ function (notice the underscore) has the same behavior as sequence but does not return a list of results. It is useful when only the side-effects of the monadic computations are important.

然后,查看TestSequence.hs

import Control.Monad

f :: String -> IO ()
f x = print x

run :: [String] -> IO ()
run xs = sequence_ . map f $ xs

我可以运行它:

λ: run ["foo", "bar"]
"foo"
"bar"

sequence_ 是否在每个 IO () 上调用 unsafePerformIO 以获得结果,即 ()?

而且, sequence_ 气馁了吗?或者,对于 IO Monad,只是使用 "at the end of the world" 到 运行 的 IO 操作列表?

不,它不会在每个 IO () 操作上调用 unsafePerformIO。事实上,它的类型甚至不特定于 IO:

sequence_ :: (Monad m, Foldable t) => t (m a) -> m ()

在旧库中,当它特定于列表时(而不是对所有 Foldables 通用),它是通过以下完全可读的方式实现的:

sequence_ [] = return ()
sequence_ (x:xs) = x >> sequence_ xs

绝对不气馁; sequence_(和它的老大哥,mapM_)非常有用,以至于它甚至是我的激励示例之一,说明为什么 Monads 作为一个抽象是有用的。