The monad instanc of Data.Stream is defined that way:
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))
That means join takes the first element of the first stream, the second element of the second stream etc, so the resulting stream can be seen as “main diagonal”, discarding all other elements.
Now there is a way to go through an infinite two-dimensional table, discovered by Georg Cantor for his proof that there are as many rational numbers as natural numbers: http://www.jcu.edu/math/vignettes/infinity.htm
Now my question is if a join using a path along all secondary diagonals (visiting every element of every stream) would be a valid implementation as well. Or would this violate one of the monad laws?
It would violate
Consider
Now
fmap f (return 1)isrepeat (f 1)and ifjoinwent through all elements, in the resultingStream, elements would repeat.As a two-dimensional table,
fmap f (return 1)looks likeand if you traverse that following the secondary diagonals, you get
and not
1 2 3 4 5 ...as withf 1.