Guest User

Untitled

a guest
Nov 16th, 2018
111
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 1.40 KB | None | 0 0
  1. trait Functor[F[_]] {
  2.   def fmap[A, B](f: A => B, a: F[A]): F[B]
  3. }
  4.  
  5. trait Applicative[F[_]] extends Functor[F] {
  6.   def ap[A, B](f: F[A => B], a: F[A]): F[B]
  7.   def point[A](a: A): F[A]
  8.   override final def fmap[A, B](f: A => B, a: F[A]) =
  9.     ap(point(f), a)
  10. }
  11.  
  12. trait Monad[F[_]] extends Applicative[F] {
  13.   def flatMap[A, B](f: A => F[B], a: F[A]): F[B]
  14.   override final def ap[A, B](f: F[A => B], a: F[A]) =
  15.     flatMap((ff: A => B) => fmap((aa: A) => ff(aa), a), f)
  16. }
  17.  
  18. object Compose {
  19.   def FunctorCompose[M[_], N[_]]
  20.     (implicit mx: Functor[M], nx: Functor[N]):
  21.         Functor[({type λ[α]=M[N[α]]})#λ] =
  22.     new Functor[({type λ[α]=M[N[α]]})#λ] {
  23.       def fmap[A, B](f: A => B, a: M[N[A]]) =
  24.           mx.fmap((na: N[A]) => nx.fmap(f, na), a)
  25.     }
  26.  
  27.   def ApplicativeCompose[M[_], N[_]]
  28.     (implicit ma: Applicative[M], na: Applicative[N]):
  29.         Applicative[({type λ[α]=M[N[α]]})#λ] =
  30.     new Applicative[({type λ[α]=M[N[α]]})#λ] {
  31.       def ap[A, B](f: M[N[A => B]], a: M[N[A]]) = {
  32.         def liftA2[X, Y, Z](f: X => Y => Z, a: M[X], b: M[Y]): M[Z] =
  33.           ma.ap(ma.fmap(f, a), b)
  34.         liftA2((ff: N[A => B]) => (aa: N[A]) => na.ap(ff, aa), f, a)
  35.       }
  36.       def point[A](a: A) =
  37.         ma point (na point a)
  38.     }
  39.  
  40.   def MonadCompose[M[_], N[_]](implicit ma: Monad[M], na: Monad[N]):
  41.       Monad[({type λ[α]=M[N[α]]})#λ] =
  42.     sys.error("todo")
  43. }
Add Comment
Please, Sign In to add comment