109

What is the Comonad typeclass in Haskell? As in Comonad from Control.Comonad in the comonad package (explanations of any other packages that provide a Comonad typeclass are also welcome). I've vaguely heard about Comonad, but all I really know about it is that is provides extract :: w a -> a, sort of a parallel to Monad's return :: a -> m a.

Bonus points for noting "real life" uses of Comonad in "real" code.

Dan Burton
  • 53,238
  • 27
  • 117
  • 198
  • I would really like to see what the difference between “co” and normal is. I know what a monad is. So if I know what the “co” means, I can conclude myself, what a comonad is, and understand it deeply. Alexey Romanov’s answer did nothing in that aspect. – Evi1M4chine Mar 01 '16 at 07:51
  • 2
    @Evi1M4chine: "co" (loosely) means "flip the arrows". Here's a rough visual of that. Consider the monadic operations: `return :: a ~> m a`, `flip bind :: (a ~> m b) -> (m a ~> m b)`. Reverse the squiggly arrows and you get the comonadic operations: `extract :: a <~ w a`, `extend :: (a <~ w b) -> (w a <~ w b)` (`extract :: w a -> a`, `extend :: (w a -> b) -> w a -> w b`) – Dan Burton Mar 03 '16 at 19:47
  • Thank you @Dan Burton… so while with a monad, you work on the “inside” (stuffing new and altered things in), with a comonad, you work on the “outside” (taking things out finally or just to alter them). Is that view correct? Because it certainly helps a lot with the deep understanding. – Evi1M4chine Mar 04 '16 at 21:06
  • comonads can be used to model co-effects. Here is a great introduction to coeffects: http://tomasp.net/coeffects/ – zeronone Jul 08 '16 at 02:07

2 Answers2

84

These links may be helpful:

  1. Evaluating cellular automata is comonadic. In particular, "whenever you see large datastructures pieced together from lots of small but similar computations there's a good chance that we're dealing with a comonad".
  2. Sequences, streams, and segments
  3. Comonads in everyday life
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 1
    +1 The first link was the one that really brought it together for me. – luqui Dec 08 '11 at 17:31
  • 52
    Link-only answer should at least contain a summary of the linked contents. Currently this answer isn't fit for being a good SO answer. Consider expanding it a bit, so that it can stand on its own without the linked articles. – Bakuriu Aug 28 '14 at 18:15
  • 4
    _"whenever you see large datastructures pieced together from lots of small but similar computations there's a good chance that we're dealing with a comonad"_ .... So does that mean that fragment shaders are comonadic? – Sam Kellett Mar 17 '15 at 12:12
  • 1
    I found [this example](https://joneshf.github.io/programming/2015/12/31/Comonads-Monoids-and-Trees.html) of `extend` to be helpful. – Chris Penner Jan 13 '17 at 19:20
25

This doesn't fully answer my question, but I wanted to put some relevant information in answer format:

"co" (loosely) means "flip the arrows". Here's a rough visual of that.

Consider the monadic operations:

return :: a ~> m a
flip (>>=) :: (a ~> m b) -> (m a ~> m b)

Reverse the squiggly arrows and you get the comonadic operations:

extract :: a <~ w a
extend :: (a <~ w b) -> (w a <~ w b)

(Written with normal arrows)

extract :: w a -> a
extend :: (w a -> b) -> w a -> w b

Notice how in this format, return is an arrow that just so happens to fit in the argument slot for flip (>>=), and the same is true of extract and extend. Monad/comonad laws say that when you put return or extract into that slot, the result is the identity arrow. The laws are the same, "just with the arrows flipped". That's a super handwavey answer but hopefully it provides some insight.

Dan Burton
  • 53,238
  • 27
  • 117
  • 198
  • 4
    Your answer goes well with avoiding the monad tutorial fallacy. Monads (and comonads) are just an interface. Although it would indeed be great to know how they were _intended_. As in: The idea behind them. – Evi1M4chine Mar 04 '16 at 21:10