ATuin

Untitled

Jun 13th, 2013
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 2.72 KB | None | 0 0
  1. package object hadaly {
  2.  
  3.   trait Functor[F[_]] {
  4.     def map[A,B](fa:F[A])(f:A => B): F[B]
  5.   }
  6.  
  7.   trait Applicative[F[_]] extends Functor[F] {
  8.     def pure[A](a: => A): F[A]
  9.     def ap[A,B](fa: F[A])(f: F[A => B]): F[B]
  10.  
  11.     override def map[A,B](fa: F[A])(f: A => B): F[B] = ap(fa)(pure(f))
  12.     def <*[A,B](fa: F[A])(fb: F[B]): F[A] = fa
  13.     def *>[A,B](fa: F[A])(fb: F[B]): F[B] = fb
  14.     def η[A](a: => A): F[A] = pure(a)
  15.     def <*>[A,B](fa: F[A])(f: F[A => B]): F[B] = ap(fa)(f)
  16.   }
  17.  
  18.   trait Monad[M[_]] extends Applicative[M] {
  19.     def bind[A,B](ma: M[A])(f: A => M[B]): M[B]
  20.  
  21.     override def map[A,B](ma: M[A])(f: A => B): M[B] = bind(ma)(a => pure(f(a)))
  22.     override def ap[A,B](ma: M[A])(f: M[A => B]): M[B] = bind(f)(f => map(ma)(f))
  23.  
  24.     def liftM[A1,R](ma: M[A1])(f: A1 => R): M[R] = ap(ma)(pure(f))
  25.     def liftM2[A1,A2,R](ma1: M[A1])(f: A1 => A2 => R)(ma2: M[A2]): M[R] =
  26.       ap(ma2)(ap(ma1)(pure(f)))
  27.   }
  28.  
  29.   trait MonadT[M[_], N[_]] extends Monad[M] {
  30.     def lift[A](m:N[A]): M[A]
  31.   }
  32.  
  33.   trait MonadOps[A, M[A]] {
  34.     val value: M[A]
  35.     def map[B](f:A => B)(implicit m:Monad[M]) = m.map(value)(f)
  36.     def ∘[B](f:A => B)(implicit m:Monad[M]) = m.map(value)(f)
  37.     def flatMap[B](f: A => M[B])(implicit m:Monad[M]) = m.bind(value)(f)
  38.     def >>=[B](f: A => M[B])(implicit m:Monad[M]) = m.bind(value)(f)
  39.     def liftM[B](f: A => B)(implicit m:Monad[M]) = m.liftM(value)(f)
  40.     def liftM2[B,C](f: A => B => C)(m2: M[B])(implicit m:Monad[M]) = m.liftM2(value)(f)(m2)
  41.   }
  42.  
  43.   trait MonadTOps[A, M[A], N[A]] {
  44.     val value: M[A]
  45.     def map[B](f:A => B)(implicit m:MonadT[M,N]) = m.map(value)(f)
  46.     def ∘[B](f:A => B)(implicit m:MonadT[M,N]) = m.map(value)(f)
  47.     def flatMap[B](f: A => M[B])(implicit m:MonadT[M,N]) = m.bind(value)(f)
  48.     def >>=[B](f: A => M[B])(implicit m:MonadT[M,N]) = m.bind(value)(f)
  49.     def liftM[B](f: A => B)(implicit m:MonadT[M,N]) = m.liftM(value)(f)
  50.     def liftM2[B,C](f: A => B => C)(m2: M[B])(implicit m:MonadT[M,N]) = m.liftM2(value)(f)(m2)
  51.   }
  52.  
  53.   case class Id[+A](value: A)
  54.  
  55.   trait IdImplicits {
  56.     implicit def monadIdentity = new Monad[Id] {
  57.       def pure[A](a: => A): Id[A] = Id(a)
  58.       def bind[A,B](ma: Id[A])(f: A => Id[B]): Id[B] = f(ma.value)
  59.     }
  60.     implicit def monadIdentityOps[A](id: Id[A]) = new MonadOps[A, Id] {
  61.       val value = id
  62.     }
  63.     implicit def idAToA[A](ida:Id[A]):A = ida.value
  64.   }
  65.  
  66.   trait ListImplicits {
  67.     implicit def monadList = new Monad[List] {
  68.       def pure[A](a: => A) = List(a)
  69.       def bind[A,B](ma:List[A])(f: A => List[B]) = ma.flatMap(f)}
  70.     implicit def monadListOps[A](l: List[A]) = new MonadOps[A, List] {
  71.       val value = l
  72.     }
  73.   }
  74.  
  75.   object Implicits
  76.     extends IdImplicits
  77.     with ListImplicits
Advertisement
Add Comment
Please, Sign In to add comment