列出 Monad

这些名单形成了一个单子。他们有一个 monad 实例,相当于这个:

instance Monad [] where 
  return x = [x]
  xs >>= f = concat (map f xs)               

我们可以使用它们来模拟计算中的非确定性。当我们使用 xs >>= f 时,函数 f::a -> [b] 被映射到列表 xs 上,获得 f 的每个元素的每个应用的结果列表列表,然后将所有结果列表连接成所有结果的列表。例如,我们使用 do-notation 计算两个非确定性数字的总和,总和由两个列表中所有整数对的列表表示,每个列表表示非确定性数字的所有可能值:

sumnd xs ys = do
  x <- xs
  y <- ys
  return (x + y)

或者等效地,在 Control.Monad 中使用 liftM2

sumnd = liftM2 (+)

我们获得:

> sumnd [1,2,3] [0,10]
[1,11,2,12,3,13]