All About Monads解释了sequence_
:
sequence_
函数(注意下划线)与sequence
具有相同的行为,但不返回结果列表。当只有monadic计算的副作用很重要时,这很有用。
然后,看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_
是否在每个unsafePerformIO
上调用IO ()
来获得结果,即()
?
并且sequence_
是否被劝阻?或者,对于IO Monad
,仅仅使用“在世界末尾”运行IO
行动列表?
答案 0 :(得分:11)
不,它没有在每个unsafePerformIO
操作上调用IO ()
。实际上,它的类型甚至不是IO
所特有的:
sequence_ :: (Monad m, Foldable t) => t (m a) -> m ()
在旧库中,当它特定于列表时(而不是所有Foldable
的泛型),它以下面的完全可读方式实现:
sequence_ [] = return ()
sequence_ (x:xs) = x >> sequence_ xs
绝对不气馁; sequence_
(和它的大哥,mapM_
)非常有用,它甚至是我为什么Monad
作为抽象有用的一个激励性例子。