So, I've been thinking, wtf is it with Stream, why is it a monad?
First, Stream functor is representable, it's just ℕ → A - so forget about all those magic definitions.
Unit is easy to implement, it corresponds to ℕ → 1, no big deal. But flattening should be defined by ℕ → ℕ × ℕ - and there's plenty, some are good, some not.
What I discovered. Here:
https://patternsinfp.wordpress.com/2010/12/31/stream-monad/ it is defined by diagonal Δ:ℕ → ℕ × ℕ - no big deal, monadic properties follow.
Except that, well, is it okay to skip values? I don't have a problem with it, but plain regular programmers must be aware, this flattening skips most of the values.
Not so in Scala. Scala people are naive in a different way. Their "flattening" of a stream of streams consists of scanning the first stream to the end, then the second... wait, are we dealing with transfinite numbers? Nobody knows, it's just funny.
Well, wait. It's not a monad. Check out this:
http://zenzike.com/posts/2010-10-21-streams-and-monad-lawsThe flattening that takes just the first stream out of the stream of streams, does not satisfy monad laws. So, Scala streams are not monads, you know.
Ok now. But because of this definition as representable, it's obvious that Stream can be a comonad.
Defined by
a monoidal operation ℕ × ℕ → ℕ
Note the
a. There's an infinite (a continuum) number of ways to define a monoid on ℕ. That's how many ways there are to define a comonad on Stream.
Actually, it's a neat way to define a comonad from a monoid. Given a monoid M, the functor M → X is a comonad.
Also, I'm afraid Kiselyov is writing something weird on all this.
But not as weird as these weird guys from IBM -
https://www.ibm.com/support/knowledgecenter/SSCRJU_3.2.1/com.ibm.swg.im.infosphere.streams.spl-standard-toolkit-reference.doc/doc/functor.html - they defined a functor! Except that they are clueless.
Tell me if/where I am wrong.
(Added in 2022). We are probably talking about free coalgebras over +1? Or?