Skip to content

Latest commit

 

History

History
124 lines (98 loc) · 7.82 KB

Free.md

File metadata and controls

124 lines (98 loc) · 7.82 KB

Free constructions

abstraction free construction
Monoid List, Vector
Functor Yoneda, Coyoneda, Density, Codensity, Right Kan Extension, Left Kan Extension, Day Convolution
Applicative FreeApplicative
Alternative Free Alternative
Traversable CoFree Traverse
Monad Free Monads, Codensity, Right Kan Extension
Comonad CoFree, Density
Profunctor Profunctor CoYoneda, Profunctor Yoneda, Tambara, Pastro, Cotambara, Copastro, TambaraSum, PastroSum, CotambaraSum, CopastroSum, Closure, Environment, CofreeTraversing, FreeTraversing, Traversing
ProfunctorFunctor Profunctor CoYoneda, Profunctor Yoneda, Tambara, Pastro, Cotambara, Copastro, TambaraSum, PastroSum, CotambaraSum, CopastroSum, Closure, Environment, CofreeTraversing, FreeTraversing
ProfunctorMonad Pastro, Copastro, PastroSum, CopastroSum, Environment, FreeTraversing
ProfunctorComonad Tambara, Cotambara, TambaraSum, CotambaraSum, Closure, CofreeTraversing
Strong Tambara, Pastro, Traversing
Costrong Cotambara, Copastro
Choice TambaraSum, PastroSum
Cochoice CotambaraSum, CopastroSum, Traversing
Closed Closure, Environment
Traversing CofreeTraversing, FreeTraversing
Arrow Free Arrow

Free Applicative

  • Implementations: Scalaz 7 Haskell

  • Resources

    • Cats docs
    • Free Applicative Functors - Paolo Capriotti, Ambrus Kaposi (paper)
    • Move Over Free Monads: Make Way for Free Applicatives! - John deGoes (video)
    • Flavours of free applicative functors - Roman Cheplyaka (blog post)

Free Monads

ADT (sometimes implemented using Fix point data type)

sealed trait FreeMonad[F[_], A]
final case class Return[F[_], A](a: A) extends FreeMonad[F, A]
final case class Suspend[F[_], A](s: F[FreeMonad[F,A]]) extends FreeMonad[F,A]

that form a Monad, if F is a functor

def freeMonad[F[_]](implicit FF: Functor[F]): Monad[FreeMonad[F, *]] = new Monad[FreeMonad[F, *]] {
  def flatMap[A, B](ma: FreeMonad[F, A])(f: A => FreeMonad[F, B]): FreeMonad[F, B] =
    ma match {
      case Return(a) => f(a)
      case Suspend(m) => Suspend{
        def ff: FreeMonad[F, A] => FreeMonad[F, B] = x => flatMap(x)(f)
        FF.map(m)(ff)
      }
  }
  def pure[A](a: A): FreeMonad[F, A] = Return(a)
}

Free Monad transformers

Cofree

Create comonad for any given type A. It is based on rose tree (multiple nodes, value in each node) where List is replaced with any Functor F. Functor F dedicdes how Cofree comonad is branching.

case class Cofree[A, F[_]](extract: A, sub: F[Cofree[A, F]])(implicit functor: Functor[F]) {
  def map[B](f: A => B): Cofree[B, F] = Cofree(f(extract), functor.map(sub)(_.map(f)))
  def duplicate: Cofree[Cofree[A, F], F] = Cofree(this, functor.map(sub)(_.duplicate))
  def extend[B](f: Cofree[A, F] => B): Cofree[B, F] = duplicate.map(f) // coKleisi composition
}

Cofree Traverse

Free Alternative

Free Arrow