Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions free/src/main/scala/cats/free/Cofree.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package cats
package free

import cats.Representable

/**
* A free comonad for some branching functor `S`. Branching is done lazily using [[Eval]].
* A tree with data at the branches, as opposed to [[Free]] which is a tree with data at the leaves.
Expand Down Expand Up @@ -147,6 +149,28 @@ sealed abstract private[free] class CofreeInstances extends CofreeInstances1 {
new CofreeComonad[S] {
def F = implicitly
}

implicit def catsFreeRepresentableForCofree[S[_]](implicit
S: Representable[S]
): Representable.Aux[Cofree[S, *], List[S.Representation]] =
new Representable[Cofree[S, *]] {
type Representation = List[S.Representation]

val F = catsFreeComonadForCofree[S](S.F)

def index[A](f: Cofree[S, A]): Representation => A = {
case Nil => f.head
case (h :: t) => index(S.index(f.tail.value)(h))(t)
}

def tabulate[A](f: Representation => A): Cofree[S, A] =
Cofree(
f(Nil),
Eval.later(
S.tabulate((r: S.Representation) => tabulate((l: List[S.Representation]) => f(r :: l)))
)
)
}
}

private trait CofreeComonad[S[_]] extends Comonad[Cofree[S, *]] {
Expand Down