PageRenderTime 39ms CodeModel.GetById 19ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/core/src/main/scala/scalaz/Name.scala

http://github.com/scalaz/scalaz
Scala | 131 lines | 118 code | 10 blank | 3 comment | 0 complexity | 2d37ded2bcb6a91f067c274e9b6bdb09 MD5 | raw file
  1package scalaz
  2
  3import scala.annotation.tailrec
  4
  5/** Call by name */
  6sealed abstract class Name[A] {
  7  def value: A
  8}
  9
 10/** Call by need */
 11final class Need[A] private(private[this] var eval: () => A) extends Name[A] {
 12  lazy val value: A = {
 13    val value0 = eval()
 14    eval = null
 15    value0
 16  }
 17}
 18
 19/** Call by value */
 20final case class Value[A](value: A) extends Name[A]
 21
 22object Name {
 23  def apply[A](a: => A) = new Name[A] {
 24    def value = a
 25  }
 26  def unapply[A](v: Name[A]): Option[A] = Some(v.value)
 27
 28  implicit val name: Monad[Name] with BindRec[Name] with Comonad[Name] with Distributive[Name] with Traverse1[Name] with Zip[Name] with Unzip[Name] with Align[Name] with Cozip[Name] =
 29    new Monad[Name] with BindRec[Name] with Comonad[Name] with Distributive[Name] with Traverse1[Name] with Zip[Name] with Unzip[Name] with Align[Name] with Cozip[Name] {
 30      override def foldMap1[A, B: Semigroup](fa: Name[A])(f: A => B) = f(fa.value)
 31      override def foldLeft[A, B](fa: Name[A], z: B)(f: (B, A) => B) = f(z, fa.value)
 32      override def foldRight[A, B](fa: Name[A], z: => B)(f: (A, => B) => B) = f(fa.value, z)
 33      def alignWith[A, B, C](f: A \&/ B => C) = (a, b) => Name(f(\&/.Both(a.value, b.value)))
 34      def cozip[A, B](x: Name[A \/ B]) = x.value.bimap(Name(_), Name(_))
 35      def foldMapRight1[A, B](fa: Name[A])(z: A => B)(f: (A, => B) => B) = z(fa.value)
 36      def traverse1Impl[G[_], A, B](fa: Name[A])(f: A => G[B])(implicit G: Apply[G]) = G.map(f(fa.value))(Name(_))
 37      def unzip[A, B](a: Name[(A, B)]) = (Name(a.value._1), Name(a.value._2))
 38      def zip[A, B](a: => Name[A], b: => Name[B]) = Name((a.value, b.value))
 39      def point[A](a: => A) = Name(a)
 40      override def map[A, B](fa: Name[A])(f: A => B) = Name(f(fa.value))
 41      override def ap[A, B](fa: => Name[A])(f: => Name[A => B]) =
 42        Name(f.value apply fa.value)
 43      def bind[A,B](v: Name[A])(f: A => Name[B]): Name[B] = Name(f(v.value).value)
 44      def cobind[A, B](fa: Name[A])(f: Name[A] => B): Name[B] = Name(f(fa))
 45      override def cojoin[A](a: Name[A]): Name[Name[A]] = Name(a)
 46      def copoint[A](p: Name[A]): A = p.value
 47      def distributeImpl[G[_], A, B](fa: G[A])(f: A => Name[B])(implicit G: Functor[G]) =
 48        Name(G.map(fa)(a => f(a).value))
 49      @tailrec
 50      def tailrecM[A, B](a: A)(f: A => Name[A \/ B]): Name[B] =
 51        f(a).value match {
 52          case -\/(a0) => tailrecM(a0)(f)
 53          case \/-(b) => Name(b)
 54        }
 55    }
 56  implicit def nameEqual[A: Equal]: Equal[Name[A]] = new Equal[Name[A]] {
 57    def equal(a1: Name[A], a2: Name[A]): Boolean = Equal[A].equal(a1.value, a2.value)
 58  }
 59  implicit def covariant: IsCovariant[Name] = IsCovariant.force
 60}
 61
 62object Need {
 63  def apply[A](a: => A): Need[A] = new Need(() => a)
 64
 65  def unapply[A](x: Need[A]): Option[A] = Some(x.value)
 66
 67  implicit val need: Monad[Need] with BindRec[Need] with Comonad[Need] with Distributive[Need] with Traverse1[Need] with Zip[Need] with Unzip[Need] with Align[Need] with Cozip[Need] =
 68    new Monad[Need] with BindRec[Need] with Comonad[Need] with Distributive[Need] with Traverse1[Need] with Zip[Need] with Unzip[Need] with Align[Need] with Cozip[Need] {
 69      override def foldMap1[A, B: Semigroup](fa: Need[A])(f: A => B) = f(fa.value)
 70      override def foldLeft[A, B](fa: Need[A], z: B)(f: (B, A) => B) = f(z, fa.value)
 71      override def foldRight[A, B](fa: Need[A], z: => B)(f: (A, => B) => B) = f(fa.value, z)
 72      def alignWith[A, B, C](f: A \&/ B => C) = (a, b) => Need(f(\&/.Both(a.value, b.value)))
 73      def cozip[A, B](x: Need[A \/ B]) = x.value.bimap(Need(_), Need(_))
 74      def foldMapRight1[A, B](fa: Need[A])(z: A => B)(f: (A, => B) => B) = z(fa.value)
 75      def traverse1Impl[G[_], A, B](fa: Need[A])(f: A => G[B])(implicit G: Apply[G]) = G.map(f(fa.value))(Need(_))
 76      def unzip[A, B](a: Need[(A, B)]) = (Need(a.value._1), Need(a.value._2))
 77      def zip[A, B](a: => Need[A], b: => Need[B]) = Need((a.value, b.value))
 78      def point[A](a: => A) = Need(a)
 79      override def map[A, B](fa: Need[A])(f: A => B) = Need(f(fa.value))
 80      override def ap[A, B](fa: => Need[A])(f: => Need[A => B]) =
 81        Need(f.value apply fa.value)
 82      def bind[A, B](v: Need[A])(f: A => Need[B]): Need[B] = Need(f(v.value).value)
 83      def cobind[A, B](fa: Need[A])(f: Need[A] => B): Need[B] = Need(f(fa))
 84      override def cojoin[A](a: Need[A]): Need[Need[A]] = Need(a)
 85      def copoint[A](p: Need[A]): A = p.value
 86      def distributeImpl[G[_], A, B](fa: G[A])(f: A => Need[B])(implicit G: Functor[G]) =
 87        Need(G.map(fa)(a => f(a).value))
 88      @tailrec
 89      def tailrecM[A, B](a: A)(f: A => Need[A \/ B]): Need[B] =
 90        f(a).value match {
 91          case -\/(a0) => tailrecM(a0)(f)
 92          case \/-(b) => Need(b)
 93        }
 94    }
 95  implicit def needEqual[A: Equal]: Equal[Need[A]] = new Equal[Need[A]] {
 96    def equal(a1: Need[A], a2: Need[A]): Boolean = Equal[A].equal(a1.value, a2.value)
 97  }
 98  implicit def covariant: IsCovariant[Value] = IsCovariant.force
 99}
100
101object Value {
102  implicit val value: Monad[Value] with BindRec[Value] with Comonad[Value] with Distributive[Value] with Traverse1[Value] with Zip[Value] with Unzip[Value] with Align[Value] with Cozip[Value] =
103    new Monad[Value] with BindRec[Value] with Comonad[Value] with Distributive[Value] with Traverse1[Value] with Zip[Value] with Unzip[Value] with Align[Value] with Cozip[Value] {
104      override def foldMap1[A, B: Semigroup](fa: Value[A])(f: A => B) = f(fa.value)
105      override def foldLeft[A, B](fa: Value[A], z: B)(f: (B, A) => B) = f(z, fa.value)
106      override def foldRight[A, B](fa: Value[A], z: => B)(f: (A, => B) => B) = f(fa.value, z)
107      def alignWith[A, B, C](f: A \&/ B => C) = (a, b) => Value(f(\&/.Both(a.value, b.value)))
108      def cozip[A, B](x: Value[A \/ B]) = x.value.bimap(Value(_), Value(_))
109      def foldMapRight1[A, B](fa: Value[A])(z: A => B)(f: (A, => B) => B) = z(fa.value)
110      def traverse1Impl[G[_], A, B](fa: Value[A])(f: A => G[B])(implicit G: Apply[G]) = G.map(f(fa.value))(Value(_))
111      def unzip[A, B](a: Value[(A, B)]) = (Value(a.value._1), Value(a.value._2))
112      def zip[A, B](a: => Value[A], b: => Value[B]) = Value((a.value, b.value))
113      def point[A](a: => A) = Value(a)
114      def bind[A, B](v: Value[A])(f: A => Value[B]): Value[B] = f(v.value)
115      def cobind[A, B](fa: Value[A])(f: Value[A] => B): Value[B] = Value(f(fa))
116      override def cojoin[A](a: Value[A]): Value[Value[A]] = Value(a)
117      def copoint[A](p: Value[A]): A = p.value
118      def distributeImpl[G[_], A, B](fa: G[A])(f: A => Value[B])(implicit G: Functor[G]) =
119        Value(G.map(fa)(a => f(a).value))
120      @tailrec
121      def tailrecM[A, B](a: A)(f: A => Value[A \/ B]): Value[B] =
122        f(a).value match {
123          case -\/(a0) => tailrecM(a0)(f)
124          case \/-(b) => Value(b)
125        }
126    }
127  implicit def valueEqual[A: Equal]: Equal[Value[A]] = new Equal[Value[A]] {
128    def equal(a1: Value[A], a2: Value[A]): Boolean = Equal[A].equal(a1.value, a2.value)
129  }
130  implicit def covariant: IsCovariant[Value] = IsCovariant.force
131}