Data.Stream的Monad实例的定义

Lan*_*dei 6 monads haskell

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))
Run Code Online (Sandbox Code Playgroud)

这意味着join获取第一个流的第一个元素,第二个流的第二个元素等,因此得到的流可以被视为"主对角线",丢弃所有其他元素.

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

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

Dan*_*her 9

它会违反

return x >>= f === f x
Run Code Online (Sandbox Code Playgroud)

考虑

f k = Cons k (f (k+1))
Run Code Online (Sandbox Code Playgroud)

现在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 ...
Run Code Online (Sandbox Code Playgroud)

如果你沿着次要对角线穿过它,你就得到了

1 1 2 1 2 3 1 2 3 4 ...
Run Code Online (Sandbox Code Playgroud)

而不是1 2 3 4 5 ...f 1.