Newer
Older
package applicative
trait Applicative[F[_]] {
def ap[A, B](ff: F[A => B])(fa: F[A]): F[B] = map2(ff, fa)((f, a) => f(a))
// implement map using pure and ap, but not flatMap/flatten
def map[A, B](fa: F[A])(f: A => B): F[B] = ???
// hint: f.curried converts `(A,B) => C` to `A => (B => C)`
def map2[A, B, C](fa: F[A], fb: F[B])(f: (A, B) => C): F[C] = ???
// then write the signature for ap and map2
// then implement one of them
def compose[G[_]](implicit G: Applicative[G]): Applicative[Lambda[a => F[G[a]]]] = {
val F = this
new Applicative[Lambda[a => F[G[a]]]] {