3
\$\begingroup\$
 trait Comonad[M[_]] {
   // map
   def >>[A,B](a: M[A])(f: A => B): M[B]

   // extract | coeta 
   def counit[A](a:M[A]): A

   // coflatten | comu
   def cojoin[A](a: M[A]): M[M[A]]
}

object Comonad {

  implicit def listComonad[A]: Comonad[List]
  =
    new Comonad[List] {

      def counit[A](lsa: List[A])
      =
        lsa match { case List(a) => a }

      def cojoin[A](lsa:List[A]): List[List[A]]
      =
        List(lsa)

      def >>[A,B](lsa: List[A])(f: A => B): List[B]
      =
        lsa map f
  }

}

So yeah I'm looking at this and I don't have that correct feeling...

Anyone mind correcting this and maybe offerring one or two other simple comonads?

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

I believe, what's bothering you is a non-total definition of counit, right? (for cojoin one possible variation is lsa.tails) Indeed, a List does not have a valid comonad instance specifically bacause of that. It does have a valid semicomonad instance though.

Things that have a valid comonad instance are, for example: Identity, NonEmptyList, Zipper, Tuple. Here's a reddit question with more examples of comonads.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.