Data.Stream的Monad实例的定义

时间:2012-07-27 09:07:47

标签: haskell monads

Data.Stream的monad instanc以这样的方式定义:

instance Monad Stream where
  return = repeat
  xs >>= f = join (fmap f xs)
    where
      join :: Stream (Stream a) -> Stream a
      join ~(Cons xs xss) = Cons (head xs) (join (map tail xss))

这意味着join获取第一个流的第一个元素,第二个流的第二个元素等,因此生成的流可以被视为“主对角线”,丢弃所有其他元素。

现在有一种方法可以通过一个无限的二维表格,由Georg Cantor发现,因为他证明了有多少有理数和自然数:http://www.jcu.edu/math/vignettes/infinity.htm

现在我的问题是,join使用沿所有辅助对角线的路径(访问每个流的每个元素)是否也是有效的实现。或者这会违反monad法律之一吗?

1 个答案:

答案 0 :(得分:9)

会违反

return x >>= f === f x

考虑

f k = Cons k (f (k+1))

现在fmap f (return 1)repeat (f 1),如果join通过了所有元素,则生成的Stream元素会重复。

作为二维表,fmap f (return 1)看起来像

1 2 3 4 ...
1 2 3 4 ...
1 2 3 4 ...

如果你在次要对角线之后遍历那个,你得到

1 1 2 1 2 3 1 2 3 4 ...

而不是1 2 3 4 5 ...f 1一样。