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法律之一吗?
它会违反
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.