package scalaz package std trait FunctionInstances1 { implicit def function1Semigroup[A, R](implicit R0: Semigroup[R]) = new Function1Semigroup[A, R] { implicit def R = R0 } } trait FunctionInstances0 extends FunctionInstances1 { implicit def function1Monoid[A, R](implicit R0: Monoid[R]) = new Function1Monoid[A, R] { implicit def R = R0 } implicit def function1Comonad[A, R](implicit A0: Monoid[A]) = new Function1Comonad[A, R] { implicit def M = A0 } } trait FunctionInstances extends FunctionInstances0 { implicit val function0Instance = new Traverse[Function0] with Monad[Function0] with Comonad[Function0] with Distributive[Function0] { def point[A](a: => A) = () => a def copoint[A](p: () => A) = p() def cobind[A, B](fa: Function0[A])(f: Function0[A] => B) = () => f(fa) def cojoin[A](a: Function0[A]): Function0[Function0[A]] = () => a def bind[A, B](fa: () => A)(f: (A) => () => B) = () => f(fa())() override def map[A,B](fa: () => A)(f: A => B) = () => f(fa()) def traverseImpl[G[_]: Applicative, A, B](fa: () => A)(f: A => G[B]) = Applicative[G].map(f(fa()))((b: B) => () => b) override def foldRight[A, B](fa: () => A, z: => B)(f: (A, => B) => B) = f(fa(), z) def distributeImpl[G[_], A, B](fa: G[A])(f: A => () => B )(implicit G: Functor[G]): () => G[B] = () => G.map(fa)(a => f(a)()) } implicit def function0Equal[R: Equal] = new Equal[() => R] { def equal(a1: () => R, a2: () => R) = Equal[R].equal(a1(), a2()) } implicit val function1Instance = new Arrow[Function1] with Category[Function1] with Choice[Function1] { def arr[A, B](f: A => B) = f def first[A, B, C](a: A => B) =(ac: (A, C)) => (a(ac._1), ac._2) def compose[A, B, C](f: B => C, g: A => B) = f compose g def id[A]: A => A = a => a def choice[A, B, C](f: => A => C, g: => B => C): (A \/ B) => C = { case -\/(a) => f(a) case \/-(b) => g(b) } override def split[A, B, C, D](f: A => B, g: C => D): ((A, C)) => (B, D) = { case (a, c) => (f(a), g(c)) } } implicit def function1Covariant[T]: Monad[({type l[a] = (T => a)})#l] with Zip[({type l[a] = (T => a)})#l] with Unzip[({type l[a] = (T => a)})#l] with Distributive[({type l[a] = (T => a)})#l] = new Monad[({type l[a] = (T => a)})#l] with Zip[({type l[a] = (T => a)})#l] with Unzip[({type l[a] = (T => a)})#l] with Distributive[({type l[a] = (T => a)})#l] { def point[A](a: => A) = _ => a def bind[A, B](fa: T => A)(f: A => T => B) = (t: T) => f(fa(t))(t) def zip[A, B](a: => T => A, b: => T => B) = t => (a(t), b(t)) def unzip[A, B](a: T => (A, B)) = (a(_)._1, a(_)._2) def distributeImpl[G[_]:Functor,A,B](fa: G[A])(f: A => T => B): T => G[B] = t => Functor[G].map(fa)(a => f(a)(t)) } implicit def function1Contravariant[R] = new Contravariant[({type l[a] = (a => R)})#l] { def contramap[A, B](r: A => R)(f: B => A) = r compose f } implicit def function2Instance[T1, T2] = new Monad[({type l[a] = ((T1, T2) => a)})#l] { def point[A](a: => A) = (t1, t2) => a def bind[A, B](fa: (T1, T2) => A)(f: (A) => (T1, T2) => B) = (t1, t2) => f(fa(t1, t2))(t1, t2) } implicit def function3Instance[T1, T2, T3] = new Monad[({type l[a] = ((T1, T2, T3) => a)})#l] { def point[A](a: => A) = (t1, t2, t3) => a def bind[A, B](fa: (T1, T2, T3) => A)(f: (A) => (T1, T2, T3) => B) = (t1, t2, t3) => f(fa(t1, t2, t3))(t1, t2, t3) } implicit def function4Instance[T1, T2, T3, T4] = new Monad[({type l[a] = ((T1, T2, T3, T4) => a)})#l] { def point[A](a: => A) = (t1, t2, t3, t4) => a def bind[A, B](fa: (T1, T2, T3, T4) => A)(f: (A) => (T1, T2, T3, T4) => B) = (t1, t2, t3, t4) => f(fa(t1, t2, t3, t4))(t1, t2, t3, t4) } implicit def function5Instance[T1, T2, T3, T4, T5] = new Monad[({type l[a] = ((T1, T2, T3, T4, T5) => a)})#l] { def point[A](a: => A) = (t1, t2, t3, t4, t5) => a def bind[A, B](fa: (T1, T2, T3, T4, T5) => A)(f: (A) => (T1, T2, T3, T4, T5) => B) = (t1, t2, t3, t4, t5) => f(fa(t1, t2, t3, t4, t5))(t1, t2, t3, t4, t5) } implicit def function6Instance[T1, T2, T3, T4, T5, T6] = new Monad[({type l[a] = ((T1, T2, T3, T4, T5, T6) => a)})#l] { def point[A](a: => A) = (t1, t2, t3, t4, t5, t6) => a def bind[A, B](fa: (T1, T2, T3, T4, T5, T6) => A)(f: (A) => (T1, T2, T3, T4, T5, T6) => B) = (t1, t2, t3, t4, t5, t6) => f(fa(t1, t2, t3, t4, t5, t6))(t1, t2, t3, t4, t5, t6) } implicit def function7Instance[T1, T2, T3, T4, T5, T6, T7] = new Monad[({type l[a] = ((T1, T2, T3, T4, T5, T6, T7) => a)})#l] { def point[A](a: => A) = (t1, t2, t3, t4, t5, t6, t7) => a def bind[A, B](fa: (T1, T2, T3, T4, T5, T6, T7) => A)(f: (A) => (T1, T2, T3, T4, T5, T6, T7) => B) = (t1, t2, t3, t4, t5, t6, t7) => f(fa(t1, t2, t3, t4, t5, t6, t7))(t1, t2, t3, t4, t5, t6, t7) } implicit def function8Instance[T1, T2, T3, T4, T5, T6, T7, T8] = new Monad[({type l[a] = ((T1, T2, T3, T4, T5, T6, T7, T8) => a)})#l] { def point[A](a: => A) = (t1, t2, t3, t4, t5, t6, t7, t8) => a def bind[A, B](fa: (T1, T2, T3, T4, T5, T6, T7, T8) => A)(f: (A) => (T1, T2, T3, T4, T5, T6, T7, T8) => B) = (t1, t2, t3, t4, t5, t6, t7, t8) => f(fa(t1, t2, t3, t4, t5, t6, t7, t8))(t1, t2, t3, t4, t5, t6, t7, t8) } } object function extends FunctionInstances // // Type class implementation traits // trait Function1Semigroup[A, R] extends Semigroup[A => R] { implicit def R: Semigroup[R] def append(f1: A => R, f2: => A => R) = a => R.append(f1(a), f2(a)) } trait Function1Monoid[A, R] extends Monoid[A => R] with Function1Semigroup[A, R] { implicit def R: Monoid[R] def zero = a => R.zero } trait Function1Comonad[M, R] extends Comonad[({type λ[α]=(M => α)})#λ] { implicit def M: Monoid[M] def cojoin[A](a: M => A) = (m1: M) => (m2: M) => a(M.append(m1, m1)) def copoint[A](p: M => A) = p(M.zero) def cobind[A, B](fa: M => A)(f: (M => A) => B) = (m1: M) => f((m2: M) => fa(M.append(m1, m2))) def map[A, B](fa: M => A)(f: A => B) = fa andThen f }