Looking through the haskell free package (http://hackage.haskell.org/package/free-3.4.2) there's a few types that seem simple and useful, that I see almost no literature on outside of haskell, the type I'm interested in now is the Free Applicative. Now I think that the free applicative builds up chains of function applications as data and maps them (out-of / over) G, (I think...)
where I'm at ...
trait Functor[F[_]] {
def map[A, B](f: A => B): F[A] => F[B]
}
trait Applicative[F[_]] extends Functor[F] {
def ap[A, B](f: F[A => B]): F[A] => F[B]
def apF[A, B](f: F[A])(x: F[A => B]): F[B]
}
trait FreeAp[F[_], A] {
def map[B](f: A => B): FreeAp[F, B] = {
this match {
case Pure(x) => Pure(f(x))
case Ap(x, y) => Ap(x, { y.map(f.compose _) })
}
}
def runAp[G[_]](phi: F ~> G, fa: FreeAp[F, A])(implicit G: Applicative[G]): G[A] = {
fa match {
case Pure(x) => G.pure(x)
case Ap(f, x) => G.apF(phi(f)) { G.map(id[A])(runAp(phi, x)) }
}
}
def runApM[B, M](phi: F ~> ({ type l[x] = M })#l, x: FreeAp[F, B])(implicit M: Monoid[M]): M = {
???
}
}
case class Pure[F[_], A](x: A) extends FreeAp[F, A]
case class Ap[F[_], A, B](x: F[A], y: FreeAp[F, A => B]) extends FreeAp[F, B]
what I'm asking for: the runAp looks so simple in haskell but I've been having some trouble translating... I need a shove in the right direction
runAp :: Applicative g => (forall x. f x -> g x) -> Ap f a -> g a
runAp _ (Pure x) = pure x
runAp u (Ap f x) = flip id <$> u f <*> runAp u x
Ideally I'd like a gentle walk through the free applicative and some help with at least the runAp implementation (but really get into it and spare no detail)
update: so I've been working with this myself and I tried implementing map and I get a variance error, the second case expression gives an error unless FreeAp is contravariant in A, but the first case expression gives an error unless FreeAp isn't contravariant in A... Any Ideas ?
update: I added the variance annotations from @Cirdec's answer and it didn't suddenly work but I played around and added a annotation [Any, B] to the Ap construction in map and now that definition type checks. so far though no luck with runAp...
update: this is the type error I'm getting on the Ap branch of the runAp pattern match ...
type mismatch; found : core01.FreeAp[F,Any => A] required: core01.FreeAp[F,A]
////
trait Forall[P[_]] {
def apply[A]: P[A]
}
trait ~>[F[_], G[_]] {
def apply[A](x: F[A]): G[A]
}
UPDATE reading: http://ro-che.info/articles/2013-03-31-flavours-of-free-applicative-functors.html, Free Applicative Functors by Paolo Capriotti
//// including the Functor & Applicative definitions above
trait FreeAp[F[_], A] { self =>
def map[B](f: A => B): FreeAp[F, B] = {
this match {
case Pure(x) => Pure(f(x))
case ap: Ap[F, α, _] => Ap(ap.x.map(f.compose(_: α => A)), ap.y)
}
}
}
case class Pure[F[_], A](x: A) extends FreeAp[F, A]
case class Ap[F[_], A, B](x: FreeAp[F, A => B], y: F[A]) extends FreeAp[F, B]
def liftAp[F[_], A](x: F[A]): FreeAp[F, A] = Ap[F, A, A](Pure(id), x)
def runAp[F[_], G[_], A](implicit G: Applicative[G]): (F ~> G) => FreeAp[F, A] => G[A] = {
(u: F ~> G) =>
(fa: FreeAp[F, A]) => fa match {
case Pure(x) => G.pure(x)
case ap: Ap[F, α, _] => {
val gf: G[(α => A) => A] = G.map(curry(flip(id[α => A])))(u(ap.y))
val gx: G[α => A] = runAp(G)(u)(ap.x)
G.ap(gf)(gx)
}
}
}
trait FreeApFunctor[F[_]] extends Functor[({ type l[x] = FreeAp[F, x] })#l] {
final override def map[A, B](f: A => B): FreeAp[F, A] => FreeAp[F, B] = _ map f
}
trait FreeApSemiapplicative[F[_]] extends Apply[({ type l[x] = FreeAp[F, x] })#l] with FreeApFunctor[F] {
final def ap[A, B](f: => FreeAp[F, A => B]): FreeAp[F, A] => FreeAp[F, B] = {
(fa: FreeAp[F, A]) => f match {
case Pure(x) => map(x)(fa)
case a: Ap[F, α, _] => Ap(ap{ map(flip[α, A, B])(a.x) }(fa), a.y)
}// ^^^
// type mismatch; found : core01.FreeAp[F,α => _] required: core01.FreeAp[F,(α, A) => B]
}
}