From 577fd61a44300b066bdc63e9b180608c2bbd6d47 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Giraudeau Date: Sun, 21 Jan 2018 22:45:23 +0100 Subject: [PATCH] Type classes: expose super class functions in sub classes. (WIP) Also ensure inheritance-based implementations via seal of type class. This avoid going through no-op invoke virtuals in most cases. WIP: Monoid/Semigroup/Functor->Monad only. --- .../src/main/scala/scalaz/BaseHierarchy.scala | 8 +-- .../src/main/scala/scalaz/Prelude.scala | 19 ++++--- .../scala/scalaz/data/ConstInstances.scala | 57 +++++++++++-------- .../scalaz/data/DisjunctionInstances.scala | 4 +- .../scala/scalaz/data/IdentityInstances.scala | 6 +- .../src/main/scala/scalaz/data/Maybe.scala | 9 +-- .../src/main/scala/scalaz/data/These.scala | 4 +- .../scala/scalaz/data/TheseInstances.scala | 11 ++-- .../scala/scalaz/typeclass/Applicative.scala | 24 ++++++-- .../scalaz/typeclass/ApplicativeClass.scala | 14 ----- .../main/scala/scalaz/typeclass/Apply.scala | 20 +++++-- .../scala/scalaz/typeclass/ApplyClass.scala | 6 -- .../main/scala/scalaz/typeclass/Bind.scala | 34 +++++++++-- .../scala/scalaz/typeclass/BindClass.scala | 25 -------- .../scala/scalaz/typeclass/CobindClass.scala | 2 +- .../main/scala/scalaz/typeclass/Comonad.scala | 2 +- .../scala/scalaz/typeclass/ComonadClass.scala | 2 +- .../scala/scalaz/typeclass/Foldable.scala | 37 ++++++++++-- .../scalaz/typeclass/FoldableClass.scala | 22 ------- .../main/scala/scalaz/typeclass/Functor.scala | 18 +++++- .../scala/scalaz/typeclass/FunctorClass.scala | 6 -- .../main/scala/scalaz/typeclass/Monad.scala | 25 ++++++-- .../scala/scalaz/typeclass/MonadClass.scala | 16 ------ .../scalaz/typeclass/MonadInstances.scala | 8 +-- .../main/scala/scalaz/typeclass/Monoid.scala | 21 +++++-- .../scala/scalaz/typeclass/MonoidClass.scala | 6 -- .../scalaz/typeclass/MonoidInstances.scala | 2 +- .../scala/scalaz/typeclass/PhantomClass.scala | 2 +- .../scala/scalaz/typeclass/Semigroup.scala | 19 ++++++- .../scalaz/typeclass/SemigroupClass.scala | 6 -- .../scala/scalaz/typeclass/Traversable.scala | 29 ++++++++-- .../scalaz/typeclass/TraversableClass.scala | 20 ------- .../typeclass/TraversableInstances.scala | 14 ++--- .../scala/scalaz/effect/IOInstances.scala | 4 +- example/src/main/tut/typeclass/Applicative.md | 4 +- example/src/main/tut/typeclass/Functor.md | 4 +- example/src/main/tut/typeclass/Monad.md | 4 +- example/src/main/tut/typeclass/Monoid.md | 27 +++------ example/src/main/tut/typeclass/Semigroup.md | 6 +- 39 files changed, 282 insertions(+), 265 deletions(-) delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/ApplicativeClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/ApplyClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/BindClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/FoldableClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/FunctorClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/MonadClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/MonoidClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/SemigroupClass.scala delete mode 100644 base/shared/src/main/scala/scalaz/typeclass/TraversableClass.scala diff --git a/base/shared/src/main/scala/scalaz/BaseHierarchy.scala b/base/shared/src/main/scala/scalaz/BaseHierarchy.scala index 0a6c57f85a..bc06702687 100644 --- a/base/shared/src/main/scala/scalaz/BaseHierarchy.scala +++ b/base/shared/src/main/scala/scalaz/BaseHierarchy.scala @@ -7,8 +7,8 @@ object BaseHierarchy { implicit def choiceProfunctor[P[_, _]](implicit P: Choice[P]): Profunctor[P] = P.profunctor implicit def monadBind[M[_]](implicit M: Monad[M]): Bind[M] = M.bind implicit def monadApplicative[M[_]](implicit M: Monad[M]): Applicative[M] = M.applicative - implicit def monadApply[M[_]](implicit M: Monad[M]): Apply[M] = M.applicative.apply - implicit def monadFunctor[M[_]](implicit M: Monad[M]): Functor[M] = M.applicative.apply.functor + implicit def monadApply[M[_]](implicit M: Monad[M]): Apply[M] = M.apply + implicit def monadFunctor[M[_]](implicit M: Monad[M]): Functor[M] = M.functor implicit def monoidSemigroup[A](implicit A: Monoid[A]): Semigroup[A] = A.semigroup implicit def traversableFoldable[T[_]](implicit T: Traversable[T]): Foldable[T] = T.foldable implicit def categoryComposable[=>:[_,_]](implicit C: Category[=>:]): Compose[=>:] = C.compose @@ -17,13 +17,13 @@ object BaseHierarchy { trait BH1 extends BH2 { implicit def bindApply[M[_]](implicit M: Bind[M]): Apply[M] = M.apply - implicit def bindFunctor[M[_]](implicit M: Bind[M]): Functor[M] = M.apply.functor + implicit def bindFunctor[M[_]](implicit M: Bind[M]): Functor[M] = M.functor implicit def strongProfunctor[P[_, _]](implicit P: Strong[P]): Profunctor[P] = P.profunctor } trait BH2 extends BH3 { implicit def applicativeApply[M[_]](implicit M: Applicative[M]): Apply[M] = M.apply - implicit def applicativeFunctor[M[_]](implicit M: Applicative[M]): Functor[M] = M.apply.functor + implicit def applicativeFunctor[M[_]](implicit M: Applicative[M]): Functor[M] = M.functor } trait BH3 extends BH4 { diff --git a/base/shared/src/main/scala/scalaz/Prelude.scala b/base/shared/src/main/scala/scalaz/Prelude.scala index 4626cecb04..0a8198d496 100644 --- a/base/shared/src/main/scala/scalaz/Prelude.scala +++ b/base/shared/src/main/scala/scalaz/Prelude.scala @@ -2,48 +2,49 @@ package scalaz trait BaseTypeclasses { type Applicative[F[_]] = typeclass.Applicative[F] + val Applicative = typeclass.Applicative type Apply[F[_]] = typeclass.Apply[F] + val Apply = typeclass.Apply type Bind[M[_]] = typeclass.Bind[M] + val Bind = typeclass.Bind type Category[=>:[_,_]] = typeclass.Category[=>:] type Choice[P[_,_]] = typeclass.Choice[P] type Cobind[F[_]] = typeclass.Cobind[F] type Comonad[F[_]] = typeclass.Comonad[F] type Compose[P[_,_]] = typeclass.Compose[P] type Foldable[T[_]] = typeclass.Foldable[T] + val Foldable = typeclass.Foldable type Functor[F[_]] = typeclass.Functor[F] + val Functor = typeclass.Functor type InvariantFunctor[F[_]] = typeclass.InvariantFunctor[F] type IsContravariant[F[_]] = typeclass.IsContravariant[F] type IsCovariant[F[_]] = typeclass.IsCovariant[F] type Monad[M[_]] = typeclass.Monad[M] + val Monad = typeclass.Monad type Monoid[T] = typeclass.Monoid[T] + val Monoid = typeclass.Monoid type Phantom[F[_]] = typeclass.Phantom[F] type Profunctor[F[_,_]] = typeclass.Profunctor[F] type Semigroup[T] = typeclass.Semigroup[T] + val Semigroup = typeclass.Semigroup type Show[A] = typeclass.Show[A] type Strong[F[_,_]] = typeclass.Strong[F] type Traversable[T[_]] = typeclass.Traversable[T] + val Traversable = typeclass.Traversable + - def Applicative[F[_]](implicit F: Applicative[F]): Applicative[F] = F - def Apply[F[_]](implicit F: Apply[F]): Apply[F] = F - def Bind[F[_]](implicit F: Bind[F]): Bind[F] = F def Category[=>:[_,_]](implicit P: Category[=>:]): Category[=>:] = P def Choice[P[_,_]](implicit P: Choice[P]): Choice[P] = P def Cobind[F[_]](implicit F: Cobind[F]): Cobind[F] = F def Comonad[F[_]](implicit F: Comonad[F]): Comonad[F] = F def Compose[P[_,_]](implicit P: Compose[P]): Compose[P] = P - def Foldable[F[_]](implicit F: Foldable[F]): Foldable[F] = F - def Functor[F[_]](implicit F: Functor[F]): Functor[F] = F def InvariantFunctor[F[_]](implicit F: InvariantFunctor[F]): InvariantFunctor[F] = F def IsContravariant[F[_]](implicit F: IsContravariant[F]): IsContravariant[F] = F def IsCovariant[F[_]](implicit F: IsCovariant[F]): IsCovariant[F] = F - def Monad[M[_]](implicit M: Monad[M]): Monad[M] = M - def Monoid[T](implicit T: Monoid[T]): Monoid[T] = T def Phantom[F[_]](implicit F: Phantom[F]): Phantom[F] = F def Profunctor[P[_,_]](implicit P: Profunctor[P]): Profunctor[P] = P - def Semigroup[T](implicit T: Semigroup[T]): Semigroup[T] = T def Show[A](implicit A: Show[A]): Show[A] = A def Strong[P[_,_]](implicit P: Strong[P]): Strong[P] = P - def Traversable[T[_]](implicit T: Traversable[T]): Traversable[T] = T } trait BaseData { diff --git a/base/shared/src/main/scala/scalaz/data/ConstInstances.scala b/base/shared/src/main/scala/scalaz/data/ConstInstances.scala index 78ac4fbd2f..a3042a3e23 100644 --- a/base/shared/src/main/scala/scalaz/data/ConstInstances.scala +++ b/base/shared/src/main/scala/scalaz/data/ConstInstances.scala @@ -1,50 +1,61 @@ package scalaz package data -import typeclass.{FoldableClass, TraversableClass} - -import Prelude._ -import FoldableClass._ -import TraversableClass._ trait ConstInstances { - implicit def constTraverse[R]: Traversable[Const[R, ?]] = new TraversableClass[Const[R, ?]] with FoldRight[Const[R, ?]] with Traverse[Const[R, ?]] { - def map[A, B](ma: Const[R, A])(f: A => B): Const[R, B] = ma.retag + implicit def constTraverse[R]: Traversable[Const[R, ?]] = new Traversable.Template[Const[R, ?]] with Traversable.DeriveSequence[Const[R, ?]] with Foldable.DeriveFoldMap[Const[R, ?]] with ConstFunctor[R] { - def traverse[F[_], A, B](ta: Const[R, A])(f: A => F[B])(implicit F: Applicative[F]): F[Const[R, B]] = + override def traverse[F[_], A, B](ta: Const[R, A])(f: A => F[B])(implicit F: Applicative[F]): F[Const[R, B]] = F.pure(ta.retag) - def foldLeft[A, B](fa: Const[R, A], z: B)(f: (B, A) => B): B = z + override def foldLeft[A, B](fa: Const[R, A], z: B)(f: (B, A) => B): B = z - def foldRight[A, B](fa: Const[R, A], z: => B)(f: (A, => B) => B): B = z + override def foldRight[A, B](fa: Const[R, A], z: => B)(f: (A, => B) => B): B = z override def toList[A](fa: Const[R, A]): List[A] = Nil } - implicit def constFunctor[R]: Functor[Const[R, ?]] = new Functor[Const[R, ?]] { - def map[A, B](fa: Const[R, A])(f: A => B): Const[R, B] = + private trait ConstFunctor[R] extends Functor.Template[Const[R, ?]] { + final override def map[A, B](fa: Const[R, A])(f: A => B): Const[R, B] = fa.retag[B] } - implicit def constApply[R](implicit R: Semigroup[R]): Apply[Const[R, ?]] = new Apply[Const[R, ?]] { - def functor: Functor[Const[R, ?]] = Const.constFunctor[R] - def ap[A, B](fa: Const[R, A])(f: Const[R, A => B]): Const[R, B] = + private trait ConstApply[R] extends Apply.Template[Const[R, ?]] with ConstFunctor[R] { + def R: Semigroup.Class[R] + final override def ap[A, B](fa: Const[R, A])(f: Const[R, A => B]): Const[R, B] = Const(R.append(fa.getConst, f.getConst)) } - implicit def constApplicative[R](implicit R: Monoid[R]): Applicative[Const[R, ?]] = new Applicative[Const[R, ?]] { - def apply: Apply[Const[R, ?]] = Const.constApply[R] - def pure[A](a: A): Const[R, A] = Const(R.empty) + private trait ConstApplicative[R] extends Applicative.Template[Const[R, ?]] with ConstApply[R] { + override def R: Monoid.Class[R] + final override def pure[A](a: A): Const[R, A] = Const(R.empty) } - implicit def constSemigroup[A, B](implicit A: Semigroup[A]): Semigroup[Const[A, B]] = new Semigroup[Const[A, B]] { - def append(a1: Const[A, B], a2: => Const[A, B]): Const[A, B] = + private trait ConstSemigroup[A, B] extends Semigroup.Template[Const[A, B]] { + def A: Semigroup.Class[A] + final override def append(a1: Const[A, B], a2: => Const[A, B]): Const[A, B] = Const(A.append(a1.getConst, a2.getConst)) } - implicit def constMonoid[A, B](implicit A: Monoid[A]): Monoid[Const[A, B]] = new Monoid[Const[A, B]] { - def semigroup: Semigroup[Const[A, B]] = implicitly - def empty: Const[A, B] = Const(A.empty) + private trait ConstMonoid[A, B] extends Monoid.Template[Const[A, B]] with ConstSemigroup[A, B] { + override def A: Monoid.Class[A] + final override def empty: Const[A, B] = Const(A.empty) + } + + implicit def constApply[R: Semigroup]: Apply[Const[R, ?]] = new ConstApply[R] { + override val R = implicitly + } + + implicit def constApplicative[R: Monoid]: Applicative[Const[R, ?]] = new ConstApplicative[R] { + override val R = implicitly + } + + implicit def constSemigroup[A: Semigroup, B]: Semigroup[Const[A, B]] = new ConstSemigroup[A, B] { + override val A = implicitly + } + + implicit def constMonoid[A: Monoid, B]: Monoid[Const[A, B]] = new ConstMonoid[A, B] { + override val A = implicitly } implicit def constShow[A, B](implicit A: Show[A]): Show[Const[A, B]] = diff --git a/base/shared/src/main/scala/scalaz/data/DisjunctionInstances.scala b/base/shared/src/main/scala/scalaz/data/DisjunctionInstances.scala index a32edf03a3..9791837246 100644 --- a/base/shared/src/main/scala/scalaz/data/DisjunctionInstances.scala +++ b/base/shared/src/main/scala/scalaz/data/DisjunctionInstances.scala @@ -1,10 +1,8 @@ package scalaz package data -import typeclass.MonadClass - trait DisjunctionInstances { - implicit def disjunctionMonad[L]: Monad[L \/ ?] = new MonadClass.Template[L \/ ?] { + implicit def disjunctionMonad[L]: Monad[L \/ ?] = new Monad.Template[L \/ ?] with Bind.DeriveFlatten[L \/ ?] { override def map[A, B](ma: L \/ A)(f: A => B): L \/ B = ma.fold[L \/ B](l => -\/(l))(r => \/-(f(r))) diff --git a/base/shared/src/main/scala/scalaz/data/IdentityInstances.scala b/base/shared/src/main/scala/scalaz/data/IdentityInstances.scala index e1588e5cd3..22c74fae53 100644 --- a/base/shared/src/main/scala/scalaz/data/IdentityInstances.scala +++ b/base/shared/src/main/scala/scalaz/data/IdentityInstances.scala @@ -1,12 +1,10 @@ package scalaz package data -import typeclass.MonadClass - trait IdentityInstances { - implicit val monad: Monad[Identity] = new MonadClass[Identity] { + implicit val monad: Monad[Identity] = new Monad.Template[Identity] { override def map[A, B](fa: Identity[A])(f: A => B): Identity[B] = Identity(f(fa.run)) - override def ap[A, B](fa: Identity[A])(f: Identity[A => B]): Identity[B] = Identity(f.run.apply(fa.run)) + override def ap[A, B](fa: Identity[A])(f: Identity[A => B]): Identity[B] = Identity(f.run(fa.run)) override def pure[A](a: A): Identity[A] = Identity(a) override def flatMap[A, B](oa: Identity[A])(f: A => Identity[B]): Identity[B] = f(oa.run) override def flatten[A](ma: Identity[Identity[A]]): Identity[A] = ma.run diff --git a/base/shared/src/main/scala/scalaz/data/Maybe.scala b/base/shared/src/main/scala/scalaz/data/Maybe.scala index cc15afe673..d914c69323 100644 --- a/base/shared/src/main/scala/scalaz/data/Maybe.scala +++ b/base/shared/src/main/scala/scalaz/data/Maybe.scala @@ -1,9 +1,6 @@ package scalaz package data -import typeclass.{MonadClass, TraversableClass} -import typeclass.FoldableClass._ - sealed trait MaybeModule { type Maybe[A] @@ -60,7 +57,7 @@ private[scalaz] object MaybeImpl extends MaybeModule { } private val instance = - new MonadClass.Template[Maybe] with TraversableClass[Maybe] with FoldRight[Maybe] { + new Monad.Template[Maybe] with Bind.DeriveFlatten[Maybe] with Traversable.Template[Maybe] with Foldable.DeriveFoldMap[Maybe] { override def ap[A, B](ma: Maybe[A])(mf: Maybe[A => B]): Maybe[B] = mf match { @@ -79,13 +76,13 @@ private[scalaz] object MaybeImpl extends MaybeModule { override def traverse[F[_], A, B](ma: Maybe[A])(f: A => F[B])(implicit F: Applicative[F]): F[Maybe[B]] = ma match { - case Some(a) => F.apply.functor.map(f(a))(just) + case Some(a) => F.map(f(a))(just) case None => F.pure(None) } override def sequence[F[_], A](ma: Maybe[F[A]])(implicit F: Applicative[F]): F[Maybe[A]] = ma match { - case Some(fa) => F.apply.functor.map(fa)(just) + case Some(fa) => F.map(fa)(just) case None => F.pure(None) } diff --git a/base/shared/src/main/scala/scalaz/data/These.scala b/base/shared/src/main/scala/scalaz/data/These.scala index 09ee6aa3bc..5ec5300c2e 100644 --- a/base/shared/src/main/scala/scalaz/data/These.scala +++ b/base/shared/src/main/scala/scalaz/data/These.scala @@ -96,8 +96,8 @@ sealed abstract class These[L, R] { /* Traversable (on the right) */ final def traverse[F[_], B](f: R => F[B])(implicit F: Applicative[F]): F[These[L, B]] = this match { case thiz @ This(_) => F.pure(thiz.pmap[B]) - case That(right) => F.apply.functor.map(f(right))(That(_)) - case Both(left, right) => F.apply.functor.map(f(right))(Both(left, _)) + case That(right) => F.map(f(right))(That(_)) + case Both(left, right) => F.map(f(right))(Both(left, _)) } /* Semigroup */ diff --git a/base/shared/src/main/scala/scalaz/data/TheseInstances.scala b/base/shared/src/main/scala/scalaz/data/TheseInstances.scala index b8009119f9..59e57f1704 100644 --- a/base/shared/src/main/scala/scalaz/data/TheseInstances.scala +++ b/base/shared/src/main/scala/scalaz/data/TheseInstances.scala @@ -1,22 +1,19 @@ package scalaz package data -import typeclass.{ BindClass, FoldableClass, MonadClass, SemigroupClass, TraversableClass } - trait TheseInstances { // implicit def bifunctor: Bifunctor[These] = ... implicit final def theseMonad[L: Semigroup]: Monad[These[L, ?]] = - new MonadClass.Template[These[L, ?]] with BindClass.Ap[These[L, ?]] { + new Monad.Template[These[L, ?]] with Bind.DeriveAp[These[L, ?]] with Bind.DeriveFlatten[These[L, ?]] { override def map[A, B](ma: These[L, A])(f: A => B) = ma.rmap(f) def flatMap[A, B](ma: These[L, A])(f: A => These[L, B]) = ma.flatMap(f) def pure[A](a: A) = That(a) } implicit final def theseTraversable[L]: Traversable[These[L, ?]] = - new TraversableClass[These[L, ?]] - with TraversableClass.Traverse[These[L, ?]] - with FoldableClass.FoldMap[These[L, ?]] { + new Traversable.Template[These[L, ?]] + with Traversable.DeriveSequence[These[L, ?]] with Foldable.DeriveToList[These[L, ?]] { def traverse[F[_]: Applicative, A, B](ta: These[L, A])(f: A => F[B]) = ta.traverse(f) def foldMap[A, B: Monoid](fa: These[L, A])(f: A => B) = fa.foldMap(f) def map[A, B](ma: These[L, A])(f: A => B) = ma.rmap(f) @@ -27,7 +24,7 @@ trait TheseInstances { } implicit final def theseSemigroup[L: Semigroup, R: Semigroup]: Semigroup[These[L, R]] = - new SemigroupClass[These[L, R]] { + new Semigroup.Template[These[L, R]] { def append(a1: These[L, R], a2: => These[L, R]) = a1.append(a2) } diff --git a/base/shared/src/main/scala/scalaz/typeclass/Applicative.scala b/base/shared/src/main/scala/scalaz/typeclass/Applicative.scala index 23cc95892d..2a42571c4b 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Applicative.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Applicative.scala @@ -1,7 +1,23 @@ package scalaz package typeclass -trait Applicative[F[_]] { - def apply: Apply[F] - def pure[A](a: A): F[A] -} +sealed trait Applicative[F[_]] extends Applicative.Class[F] + +object Applicative { + + trait Class[F[_]] extends Apply.Class[F] { + def pure[A](a: A): F[A] + + def applicative: Applicative[F] + } + + trait Template[F[_]] extends Apply.Template[F] with Applicative[F] { + final override def applicative = this + } + + trait DeriveMap[F[_]] extends Monad.Alt[DeriveMap[F]] { self: Class[F] => + final override def map[A, B](ma: F[A])(f: (A) => B): F[B] = ap(ma)(pure(f)) + } + + def apply[F[_]](implicit F: Applicative[F]): Applicative[F] = F +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/ApplicativeClass.scala b/base/shared/src/main/scala/scalaz/typeclass/ApplicativeClass.scala deleted file mode 100644 index f9e1fcef23..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/ApplicativeClass.scala +++ /dev/null @@ -1,14 +0,0 @@ -package scalaz -package typeclass - -trait ApplicativeClass[F[_]] extends Applicative[F] with ApplyClass[F] { - final def applicative: Applicative[F] = this -} - -object ApplicativeClass { - trait Template[F[_]] extends ApplicativeClass[F] with Map[F] - - trait Map[F[_]] { self: Applicative[F] with Apply[F] with Functor[F] => - override def map[A, B](ma: F[A])(f: (A) => B): F[B] = ap(ma)(pure(f)) - } -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/Apply.scala b/base/shared/src/main/scala/scalaz/typeclass/Apply.scala index c24df0dd11..66fb4d0999 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Apply.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Apply.scala @@ -1,7 +1,19 @@ package scalaz package typeclass -trait Apply[F[_]] { - def functor: Functor[F] - def ap[A, B](fa: F[A])(f: F[A => B]): F[B] -} +sealed trait Apply[F[_]] extends Apply.Class[F] + +object Apply { + + trait Class[F[_]] extends Functor.Class[F] { + def ap[A, B](fa: F[A])(f: F[A => B]): F[B] + + def apply: Apply[F] + } + + trait Template[F[_]] extends Functor.Template[F] with Apply[F] { + final override def apply = this + } + + def apply[F[_]](implicit F: Apply[F]): Apply[F] = F +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/ApplyClass.scala b/base/shared/src/main/scala/scalaz/typeclass/ApplyClass.scala deleted file mode 100644 index a0f8ea5633..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/ApplyClass.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scalaz -package typeclass - -trait ApplyClass[F[_]] extends Apply[F] with FunctorClass[F] { - implicit final def apply: Apply[F] = this -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/Bind.scala b/base/shared/src/main/scala/scalaz/typeclass/Bind.scala index 23c89cbe15..94ce10b38b 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Bind.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Bind.scala @@ -1,8 +1,32 @@ package scalaz package typeclass -trait Bind[M[_]] { - def apply: Apply[M] - def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B] - def flatten[A](ma: M[M[A]]): M[A] -} +sealed trait Bind[M[_]] extends Bind.Class[M] + +object Bind { + + trait Class[M[_]] extends Apply.Class[M] { + def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B] + def flatten[A](ma: M[M[A]]): M[A] + + def bind: Bind[M] + } + + trait Template[M[_]] extends Apply.Template[M] with Bind[M] { + final override def bind = this + } + + trait DeriveAp[M[_]] extends Monad.Alt[DeriveAp[M]] { self: Class[M] => + final override def ap[A, B](fa: M[A])(f: M[A => B]): M[B] = flatMap(f)(map(fa)) + } + + trait Alt[D <: Alt[D]] + trait DeriveFlatten[M[_]] extends Alt[DeriveFlatten[M]] { self: Class[M] => + final override def flatten[A](ma: M[M[A]]): M[A] = flatMap(ma)(identity) + } + trait DeriveFlatMap[M[_]] extends Alt[DeriveFlatMap[M]] { self: Class[M] => + final override def flatMap[A, B](ma: M[A])(f: (A) => M[B]): M[B] = flatten(map(ma)(f)) + } + + def apply[F[_]](implicit F: Bind[F]): Bind[F] = F +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/BindClass.scala b/base/shared/src/main/scala/scalaz/typeclass/BindClass.scala deleted file mode 100644 index 333919c37e..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/BindClass.scala +++ /dev/null @@ -1,25 +0,0 @@ -package scalaz -package typeclass - -trait BindClass[M[_]] extends Bind[M] with ApplyClass[M] { - final def bind: Bind[M] = this -} - -object BindClass { - trait Template[M[_]] extends BindClass[M] with Ap[M] - - trait Ap[M[_]] { self: Bind[M] with Apply[M] with Functor[M] => - override def ap[A, B](fa: M[A])(f: M[A => B]): M[B] = flatMap(f)(map(fa)) - } - - trait FlatMap[M[_]] extends Alt[FlatMap[M]] { self: Bind[M] => - override def flatMap[A, B](ma: M[A])(f: A => M[B]): M[B] - override def flatten[A](ma: M[M[A]]): M[A] = flatMap(ma)(identity) - } - trait Flatten[M[_]] extends Alt[Flatten[M]] { self: Bind[M] => - override def flatten[A](ma: M[M[A]]): M[A] - override def flatMap[A, B](ma: M[A])(f: (A) => M[B]): M[B] = flatten(apply.functor.map(ma)(f)) - } - - trait Alt[D <: Alt[D]] { self: D => } -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/CobindClass.scala b/base/shared/src/main/scala/scalaz/typeclass/CobindClass.scala index 98d135fbdd..d456079932 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/CobindClass.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/CobindClass.scala @@ -1,7 +1,7 @@ package scalaz package typeclass -trait CobindClass[F[_]] extends Cobind[F] with FunctorClass[F] { +trait CobindClass[F[_]] extends Cobind[F] with Functor.Template[F] { final def cobind: Cobind[F] = this } diff --git a/base/shared/src/main/scala/scalaz/typeclass/Comonad.scala b/base/shared/src/main/scala/scalaz/typeclass/Comonad.scala index ac691a4b4f..e779d0e082 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Comonad.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Comonad.scala @@ -2,7 +2,7 @@ package scalaz package typeclass trait Comonad[F[_]] { - def cobind: Cobind[F] + def cobind: Cobind[F] def copoint[A](fa: F[A]): A } diff --git a/base/shared/src/main/scala/scalaz/typeclass/ComonadClass.scala b/base/shared/src/main/scala/scalaz/typeclass/ComonadClass.scala index d70c778fb7..fad8f3c6af 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/ComonadClass.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/ComonadClass.scala @@ -1,7 +1,7 @@ package scalaz package typeclass -trait ComonadClass[F[_]] extends Comonad[F] with CobindClass[F] with FunctorClass[F] { +trait ComonadClass[F[_]] extends Comonad[F] with CobindClass[F] with Functor.Class[F] { final def comonad: Comonad[F] = this } diff --git a/base/shared/src/main/scala/scalaz/typeclass/Foldable.scala b/base/shared/src/main/scala/scalaz/typeclass/Foldable.scala index 47d9392550..f58b5cf245 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Foldable.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Foldable.scala @@ -1,14 +1,39 @@ package scalaz package typeclass -trait Foldable[F[_]] { +sealed trait Foldable[F[_]] extends Foldable.Class[F] - def foldMap[A, B: Monoid](fa: F[A])(f: A => B): B +object Foldable { - def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B): B + trait Class[F[_]] { - def foldLeft[A, B](fa: F[A], z: B)(f: (B, A) => B): B // = TODO default implementation from foldmap + def foldMap[A, B: Monoid](fa: F[A])(f: A => B): B - // TODO Use IList (`toIList`) - def toList[A](fa: F[A]): List[A] = foldLeft(fa, List[A]())((t, h) => h :: t).reverse + def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B): B + + def foldLeft[A, B](fa: F[A], z: B)(f: (B, A) => B): B // = TODO default implementation from foldmap + + // TODO Use IList (`toIList`) + def toList[A](fa: F[A]): List[A] + + def foldable: Foldable[F] + } + + trait Template[F[_]] extends Foldable[F] { + final override def foldable = this + } + + trait DeriveToList[F[_]] { self: Class[F] => + final override def toList[A](fa: F[A]) = foldLeft(fa, List[A]())((t, h) => h :: t).reverse + } + + trait Alt[D <: Alt[D]] + trait DeriveFoldRight[F[_]] extends Alt[DeriveFoldRight[F]] { self : Class[F] => + override def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B): B // = TODO implement from foldmap/endo + } + trait DeriveFoldMap[F[_]] extends Alt[DeriveFoldMap[F]] { self : Class[F] => + final override def foldMap[A, B](fa: F[A])(f: A => B)(implicit B: Monoid[B]) = foldRight(fa, B.empty)((a, b) => B.append(f(a),b)) + } + + def apply[F[_]](implicit F: Foldable[F]): Foldable[F] = F } \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/FoldableClass.scala b/base/shared/src/main/scala/scalaz/typeclass/FoldableClass.scala deleted file mode 100644 index 0b98003a8b..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/FoldableClass.scala +++ /dev/null @@ -1,22 +0,0 @@ -package scalaz -package typeclass - -import Prelude._ - -trait FoldableClass[F[_]] extends Foldable[F]{ - final def foldable: Foldable[F] = this -} - -object FoldableClass { - trait FoldMap[F[_]] extends Alt[FoldMap[F]] { self : Foldable[F] => - override def foldMap[A, B: Monoid](fa: F[A])(f: A => B): B - override def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B): B // = TODO implement from foldmap/endo - } - - trait FoldRight[F[_]] extends Alt[FoldRight[F]] { self : Foldable[F] => - override def foldRight[A, B](fa: F[A], z: => B)(f: (A, => B) => B): B - override def foldMap[A, B: Monoid](fa: F[A])(f: A => B) = foldRight(fa, Monoid[B].empty)((a, b) => Semigroup[B].append(f(a),b)) - } - - trait Alt[D <: Alt[D]] { self: D => } -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/Functor.scala b/base/shared/src/main/scala/scalaz/typeclass/Functor.scala index becd8edb12..cda0a23a55 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Functor.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Functor.scala @@ -1,6 +1,18 @@ package scalaz package typeclass -trait Functor[F[_]] { - def map[A, B](ma: F[A])(f: A => B): F[B] -} +sealed trait Functor[F[_]] extends Functor.Class[F] + +object Functor { + trait Class[F[_]] { + def map[A, B](ma: F[A])(f: A => B): F[B] + + def functor: Functor[F] + } + + trait Template[F[_]] extends Functor[F] { + final override def functor = this + } + + def apply[F[_]](implicit F: Functor[F]): Functor[F] = F +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/FunctorClass.scala b/base/shared/src/main/scala/scalaz/typeclass/FunctorClass.scala deleted file mode 100644 index 08610d6923..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/FunctorClass.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scalaz -package typeclass - -trait FunctorClass[F[_]] extends Functor[F]{ - final def functor: Functor[F] = this -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/Monad.scala b/base/shared/src/main/scala/scalaz/typeclass/Monad.scala index c68a5c887d..2723e02389 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Monad.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Monad.scala @@ -1,7 +1,24 @@ package scalaz package typeclass -trait Monad[M[_]] { - def applicative: Applicative[M] - def bind: Bind[M] -} +sealed trait Monad[M[_]] extends Monad.Class[M] + +object Monad { + + trait Class[M[_]] extends Applicative.Class[M] with Bind.Class[M] { + def monad: Monad[M] + } + + trait Template[M[_]] extends Applicative.Template[M] with Bind.Template[M] with Monad[M] { + final override def monad = this + } + + trait DeriveMap[M[_]] extends Bind.Alt[Bind.DeriveFlatten[M]] { self: Class[M] => + final override def map[A, B](ma: M[A])(f: (A) => B): M[B] = flatMap(ma)(a => pure(f(a))) + } + + trait Alt[D <: Alt[D]] + + def apply[M[_]](implicit M: Monad[M]): Monad[M] = M + +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/MonadClass.scala b/base/shared/src/main/scala/scalaz/typeclass/MonadClass.scala deleted file mode 100644 index a6b186c84a..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/MonadClass.scala +++ /dev/null @@ -1,16 +0,0 @@ -package scalaz -package typeclass - -import BindClass._ - -trait MonadClass[M[_]] extends Monad[M] with BindClass[M] with ApplicativeClass[M] { - final def monad: Monad[M] = this -} - -object MonadClass { - trait Template[M[_]] extends MonadClass[M] with Map[M] - - trait Map[M[_]] extends FlatMap[M] { self: Monad[M] with Bind[M] with Applicative[M] with Functor[M] => - override def map[A, B](ma: M[A])(f: (A) => B): M[B] = flatMap(ma)(a => pure(f(a))) - } -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/MonadInstances.scala b/base/shared/src/main/scala/scalaz/typeclass/MonadInstances.scala index 2305f2ab80..df1eb6808e 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/MonadInstances.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/MonadInstances.scala @@ -2,21 +2,21 @@ package scalaz package typeclass trait MonadInstances { - implicit val optionMonad: Monad[Option] = new MonadClass.Template[Option] { + implicit val optionMonad: Monad[Option] = new Monad.Template[Option] with Bind.DeriveFlatten[Option] { override def ap[A, B](oa: Option[A])(f: Option[A => B]): Option[B] = oa.flatMap(a => f.map(_(a))) override def flatMap[A, B](oa: Option[A])(f: A => Option[B]): Option[B] = oa.flatMap(f) override def map[A, B](oa: Option[A])(f: A => B): Option[B] = oa.map(f) override def pure[A](a: A): Option[A] = Option(a) } - implicit val listMonad: Monad[List] = new MonadClass.Template[List] { + implicit val listMonad: Monad[List] = new Monad.Template[List] with Bind.DeriveFlatten[List] { override def ap[A, B](xs: List[A])(f: List[A => B]): List[B] = xs.flatMap(a => f.map(_(a))) override def flatMap[A, B](xs: List[A])(f: A => List[B]): List[B] = xs.flatMap(f) override def map[A, B](xs: List[A])(f: A => B): List[B] = xs.map(f) override def pure[A](a: A): List[A] = List(a) } - implicit val functionMonad: Monad[Function0] = new MonadClass.Template[Function0] { + implicit val functionMonad: Monad[Function0] = new Monad.Template[Function0] with Bind.DeriveFlatten[Function0] { override def ap[A, B](fab: Function0[A])(f: Function0[A => B]): Function0[B] = () => f()(fab()) override def map[A, B](fab: Function0[A])(f: A => B): Function0[B] = () => f(fab()) override def flatMap[A, B](fab: Function0[A])(f: A => Function0[B]): Function0[B] = () => f(fab())() @@ -24,7 +24,7 @@ trait MonadInstances { } - implicit def function1Monad[C]: Monad[Function1[C, ?]] = new MonadClass.Template[Function1[C, ?]] { + implicit def function1Monad[C]: Monad[Function1[C, ?]] = new Monad.Template[Function1[C, ?]] with Bind.DeriveFlatten[Function1[C, ?]] { override def ap[A, B](fab: Function1[C, A])(f: Function1[C, A => B]): Function1[C, B] = (c: C) => f(c)(fab(c)) override def map[A, B](fab: Function1[C, A])(f: A => B): Function1[C, B] = fab andThen f override def flatMap[A, B](fab: Function1[C, A])(f: A => Function1[C, B]): Function1[C, B] = (c: C) => f(fab(c))(c) diff --git a/base/shared/src/main/scala/scalaz/typeclass/Monoid.scala b/base/shared/src/main/scala/scalaz/typeclass/Monoid.scala index 0410915e37..b3a6657acb 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Monoid.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Monoid.scala @@ -1,7 +1,20 @@ package scalaz package typeclass -trait Monoid[A] { - def semigroup: Semigroup[A] - def empty: A -} +sealed trait Monoid[A] extends Monoid.Class[A] + +object Monoid { + + trait Class[A] extends Semigroup.Class[A] { + def empty: A + + def monoid: Monoid[A] + } + + trait Template[A] extends Semigroup.Template[A] with Monoid[A] { + final override def monoid = this + } + + def apply[T](implicit T: Monoid[T]): Monoid[T] = T + +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/MonoidClass.scala b/base/shared/src/main/scala/scalaz/typeclass/MonoidClass.scala deleted file mode 100644 index 8de3c8f344..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/MonoidClass.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scalaz -package typeclass - -trait MonoidClass[A] extends Monoid[A] with SemigroupClass[A]{ - final def monoid: Monoid[A] = this -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/MonoidInstances.scala b/base/shared/src/main/scala/scalaz/typeclass/MonoidInstances.scala index ab0ccbcc28..a86dc52646 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/MonoidInstances.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/MonoidInstances.scala @@ -3,7 +3,7 @@ package typeclass trait MonoidInstances { - implicit val stringMonoid: Monoid[String] = new MonoidClass[String] { + implicit val stringMonoid: Monoid[String] = new Monoid.Template[String] { def append(a1: String, a2: => String) = a1 + a2 def empty = "" } diff --git a/base/shared/src/main/scala/scalaz/typeclass/PhantomClass.scala b/base/shared/src/main/scala/scalaz/typeclass/PhantomClass.scala index 01910fa556..4434d95f0d 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/PhantomClass.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/PhantomClass.scala @@ -1,7 +1,7 @@ package scalaz package typeclass -trait PhantomClass[F[_]] extends Phantom[F] with Functor[F] with Contravariant[F] { +trait PhantomClass[F[_]] extends Phantom[F] with Functor.Template[F] with Contravariant[F] { final def phantom: Phantom[F] = this } diff --git a/base/shared/src/main/scala/scalaz/typeclass/Semigroup.scala b/base/shared/src/main/scala/scalaz/typeclass/Semigroup.scala index b1e87bbfaf..70890a5085 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Semigroup.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Semigroup.scala @@ -1,6 +1,19 @@ package scalaz package typeclass -trait Semigroup[A] { - def append(a1: A, a2: => A): A -} +sealed trait Semigroup[A] extends Semigroup.Class[A] + +object Semigroup { + + trait Class[A] { + def append(a1: A, a2: => A): A + + def semigroup: Semigroup[A] + } + + trait Template[A] extends Semigroup[A] { + final override def semigroup = this + } + + def apply[T](implicit T: Semigroup[T]): Semigroup[T] = T +} \ No newline at end of file diff --git a/base/shared/src/main/scala/scalaz/typeclass/SemigroupClass.scala b/base/shared/src/main/scala/scalaz/typeclass/SemigroupClass.scala deleted file mode 100644 index 18b654e8f0..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/SemigroupClass.scala +++ /dev/null @@ -1,6 +0,0 @@ -package scalaz -package typeclass - -trait SemigroupClass[A] extends Semigroup[A]{ - final def semigroup: Semigroup[A] = this -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/Traversable.scala b/base/shared/src/main/scala/scalaz/typeclass/Traversable.scala index b44f045f33..693e652dde 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/Traversable.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/Traversable.scala @@ -1,11 +1,28 @@ package scalaz package typeclass -trait Traversable[T[_]] { - def functor: Functor[T] - def foldable: Foldable[T] +sealed trait Traversable[T[_]] extends Traversable.Class[T] - def traverse[F[_], A, B](ta: T[A])(f: A => F[B])(implicit F: Applicative[F]): F[T[B]] - def sequence[F[_], A](ta: T[F[A]])(implicit F: Applicative[F]): F[T[A]] -} +object Traversable { + + trait Class[T[_]] extends Functor.Class[T] with Foldable.Class[T] { + def traverse[F[_]: Applicative, A, B](ta: T[A])(f: A => F[B]): F[T[B]] + def sequence[F[_]: Applicative, A](ta: T[F[A]]): F[T[A]] + + def traversable: Traversable[T] + } + trait Template[T[_]] extends Functor.Template[T] with Foldable.Template[T] with Traversable[T] { + final override def traversable = this + } + + trait Alt[D <: Alt[D]] + trait DeriveSequence[T[_]] extends Alt[DeriveSequence[T]] { self : Class[T] => + final override def sequence[F[_]: Applicative, A](ta: T[F[A]]): F[T[A]] = traverse(ta)(identity) + } + trait DeriveTraverse[T[_]] extends Alt[DeriveTraverse[T]] { self : Class[T] => + final override def traverse[F[_]: Applicative, A, B](ta: T[A])(f: A => F[B]): F[T[B]] = sequence(map(ta)(f)) + } + + def apply[T[_]](implicit T: Traversable[T]): Traversable[T] = T +} diff --git a/base/shared/src/main/scala/scalaz/typeclass/TraversableClass.scala b/base/shared/src/main/scala/scalaz/typeclass/TraversableClass.scala deleted file mode 100644 index 773f55e626..0000000000 --- a/base/shared/src/main/scala/scalaz/typeclass/TraversableClass.scala +++ /dev/null @@ -1,20 +0,0 @@ -package scalaz -package typeclass - -trait TraversableClass[T[_]] extends Traversable[T] with FunctorClass[T] with FoldableClass[T] { - final def traversable: Traversable[T] = this -} - -object TraversableClass { - trait Traverse[T[_]] extends Alt[Traverse[T]] { self : Traversable[T] => - override def traverse[F[_], A, B](ta: T[A])(f: A => F[B])(implicit F: Applicative[F]): F[T[B]] - override def sequence[F[_], A](ta: T[F[A]])(implicit F: Applicative[F]): F[T[A]] = traverse(ta)(identity) - } - - trait Sequence[T[_]] extends Alt[Sequence[T]] { self : Traversable[T] => - override def sequence[F[_], A](ta: T[F[A]])(implicit F: Applicative[F]): F[T[A]] - override def traverse[F[_], A, B](ta: T[A])(f: A => F[B])(implicit F: Applicative[F]): F[T[B]] = sequence(functor.map(ta)(f)) - } - - trait Alt[D <: Alt[D]] { self: D => } -} diff --git a/base/shared/src/main/scala/scalaz/typeclass/TraversableInstances.scala b/base/shared/src/main/scala/scalaz/typeclass/TraversableInstances.scala index ddf56ed614..71fe132170 100644 --- a/base/shared/src/main/scala/scalaz/typeclass/TraversableInstances.scala +++ b/base/shared/src/main/scala/scalaz/typeclass/TraversableInstances.scala @@ -1,17 +1,11 @@ package scalaz package typeclass -import FoldableClass._ -import TraversableClass._ - trait TraversableInstances { - implicit val listTraversable: Traversable[List] = new TraversableClass[List] with Traverse[List] with FoldRight[List] { + implicit val listTraversable: Traversable[List] = new Traversable.Template[List] with Traversable.DeriveSequence[List] with Foldable.DeriveFoldMap[List] { override def traverse[F[_], A, B](ta: List[A])(f: A => F[B])(implicit F: Applicative[F]): F[List[B]] = ta.foldLeft[F[List[B]]](F.pure(List.empty[B])) { (flb, a) => { - val functor: Functor[F] = F.apply.functor - val apply: Apply[F] = F.apply - - apply.ap(flb)(functor.map(f(a))(b => (xs: List[B]) => b :: xs)) + F.ap(flb)(F.map(f(a))(b => (xs: List[B]) => b :: xs)) }} override def foldLeft[A, B](fa: List[A], z: B)(f: (B, A) => B): B = fa.foldLeft(z)(f) @@ -23,9 +17,9 @@ trait TraversableInstances { override def map[A, B](fa: List[A])(f: A => B) = fa.map(f) } - implicit def tuple2Traversable[C]: Traversable[Tuple2[C, ?]] = new TraversableClass[Tuple2[C, ?]] with Traverse[Tuple2[C, ?]] with FoldRight[Tuple2[C, ?]] { + implicit def tuple2Traversable[C]: Traversable[Tuple2[C, ?]] = new Traversable.Template[Tuple2[C, ?]] with Traversable.DeriveSequence[Tuple2[C, ?]] with Foldable.DeriveFoldMap[Tuple2[C, ?]] { def traverse[F[_], A, B](ta: Tuple2[C, A])(f: A => F[B])(implicit F: Applicative[F]): F[Tuple2[C, B]] = - F.apply.functor.map(f(ta._2))(b => (ta._1, b)) + F.map(f(ta._2))(b => (ta._1, b)) override def foldLeft[A, B](ta: Tuple2[C, A], z: B)(f: (B, A) => B): B = f(z, ta._2) diff --git a/effect/shared/src/main/scala/scalaz/effect/IOInstances.scala b/effect/shared/src/main/scala/scalaz/effect/IOInstances.scala index d238a42e7e..d75bd3d431 100644 --- a/effect/shared/src/main/scala/scalaz/effect/IOInstances.scala +++ b/effect/shared/src/main/scala/scalaz/effect/IOInstances.scala @@ -1,10 +1,10 @@ // Copyright (C) 2017 John A. De Goes. All rights reserved. package scalaz.effect -import scalaz.typeclass.{Monad, MonadClass} +import scalaz.typeclass.{Bind, Monad} trait IOInstances { - implicit val monad: Monad[IO] = new MonadClass.Template[IO] { + implicit val monad: Monad[IO] = new Monad.Template[IO] with Bind.DeriveFlatten[IO] { override final def map[A, B](ma: IO[A])(f: A => B): IO[B] = ma.map(f) diff --git a/example/src/main/tut/typeclass/Applicative.md b/example/src/main/tut/typeclass/Applicative.md index 7c9dd204cc..f8e2f53d48 100644 --- a/example/src/main/tut/typeclass/Applicative.md +++ b/example/src/main/tut/typeclass/Applicative.md @@ -16,9 +16,9 @@ import scalaz.Scalaz._ ## Instance declaration ```tut -import scalaz.typeclass.ApplicativeClass +import scalaz.Prelude._ -implicit val listap: Applicative[List] = new ApplicativeClass[List] { +implicit val listap: Applicative[List] = new Applicative.Template[List] { def pure[A](a: A): List[A] = List(a) def ap[A, B](fa: List[A])(f: List[A => B]): List[B] = fa.zip(f).map(t => t._2(t._1)) def map[A, B](ma: List[A])(f: A => B): List[B] = ma.map(f) diff --git a/example/src/main/tut/typeclass/Functor.md b/example/src/main/tut/typeclass/Functor.md index 7bdb940325..6aabac8382 100644 --- a/example/src/main/tut/typeclass/Functor.md +++ b/example/src/main/tut/typeclass/Functor.md @@ -22,7 +22,9 @@ import Scalaz._ ## Instance declaration ```tut -val listFunctor: Functor[List] = new Functor[List] { +import scalaz.Prelude._ + +val listFunctor: Functor[List] = new Functor.Template[List] { def map[A, B](ma: List[A])(f: A => B): List[B] = ma match { case Nil => Nil case x :: xs => f(x) :: map(xs)(f) diff --git a/example/src/main/tut/typeclass/Monad.md b/example/src/main/tut/typeclass/Monad.md index 4bae834a2b..480026de06 100644 --- a/example/src/main/tut/typeclass/Monad.md +++ b/example/src/main/tut/typeclass/Monad.md @@ -22,9 +22,9 @@ import scalaz.Scalaz._ ## Instance declaration ```tut -import scalaz.typeclass.MonadClass +import scalaz.Prelude._ -val listMonad: Monad[List] = new MonadClass[List] { +val listMonad: Monad[List] = new Monad.Template[List] { def pure[A](a: A): List[A] = List(a) def ap[A, B](fa: List[A])(f: List[A => B]): List[B] = fa.zip(f).map(t => t._2(t._1)) def flatMap[A, B](ma: List[A])(f: A => List[B]): List[B] = ma.flatMap(f) diff --git a/example/src/main/tut/typeclass/Monoid.md b/example/src/main/tut/typeclass/Monoid.md index ba410b3032..96f43c9f99 100644 --- a/example/src/main/tut/typeclass/Monoid.md +++ b/example/src/main/tut/typeclass/Monoid.md @@ -21,33 +21,22 @@ import Scalaz._ ## Instance declaration ```tut -def ListSemigroup[A]: Semigroup[List[A]] = new Semigroup[List[A]] { - def append(a1: List[A], a2: => List[A]) = a1 ++ a2 -} - -implicit def ListMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] { - val semigroup = ListSemigroup[A] - val empty = List.empty[A] -} -``` +{ +import scalaz.Prelude._ -Instances can also be defined without the intermediary `Semigroup` by using `MonoidClass`: - -```tut -import scalaz.typeclass.MonoidClass - -implicit def StringMonoid: Monoid[String] = new MonoidClass[String] { +implicit def StringMonoid: Monoid[String] = new Monoid.Template[String] { def append(a1: String, a2: => String) = a1 + a2 val empty = "" } +} ``` ## Usage ```tut -val l1 = List(1, 2, 3) -val l2 = List(4, 5, 6) +val s1 = "Hello" +val s2 = " World" -val l = l1.append(l2) -l.append(ListMonoid.empty) +val s = s1.append(s2) +s.append(Monoid[String].empty) ``` diff --git a/example/src/main/tut/typeclass/Semigroup.md b/example/src/main/tut/typeclass/Semigroup.md index 368087adf3..7ff0d1e590 100644 --- a/example/src/main/tut/typeclass/Semigroup.md +++ b/example/src/main/tut/typeclass/Semigroup.md @@ -20,7 +20,9 @@ import Scalaz._ ## Instance declaration ```tut -implicit val StringSemigroup = new Semigroup[String] { +import scalaz.Prelude._ + +implicit val StringSemigroup: Semigroup[String] = new Semigroup.Template[String] { def append(a1: String, a2: => String) = a1 + a2 } ``` @@ -28,6 +30,6 @@ implicit val StringSemigroup = new Semigroup[String] { ## Usage ```tut -StringSemigroup.append("hello", "world") +Semigroup[String].append("hello", "world") "hello".append("world") ```