Skip to content

Commit

Permalink
nest to compose
Browse files Browse the repository at this point in the history
- Rename unwrapped composed instances to Composed instead of Nested
- Move instances to Composed.scala
- Rename methods from nest to compose
  • Loading branch information
adelbertc committed Jun 3, 2016
1 parent cae7bd0 commit 86ce5ed
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 198 deletions.
6 changes: 2 additions & 4 deletions core/src/main/scala/cats/Alternative.scala
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package cats

import cats.data.NestedAlternative

import simulacrum.typeclass

@typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F] { self =>
override def nest[G[_]: Applicative]: Alternative[Lambda[A => F[G[A]]]] =
new NestedAlternative[F, G] {
override def compose[G[_]: Applicative]: Alternative[Lambda[A => F[G[A]]]] =
new ComposedAlternative[F, G] {
val F = self
val G = Applicative[G]
}
Expand Down
5 changes: 2 additions & 3 deletions core/src/main/scala/cats/Applicative.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cats

import cats.data.NestedApplicative
import cats.std.list._
import simulacrum.typeclass

Expand Down Expand Up @@ -45,8 +44,8 @@ import simulacrum.typeclass
def sequence[G[_], A](as: G[F[A]])(implicit G: Traverse[G]): F[G[A]] =
G.sequence(as)(this)

def nest[G[_]: Applicative]: Applicative[Lambda[A => F[G[A]]]] =
new NestedApplicative[F, G] {
def compose[G[_]: Applicative]: Applicative[Lambda[A => F[G[A]]]] =
new ComposedApplicative[F, G] {
val F = self
val G = Applicative[G]
}
Expand Down
6 changes: 2 additions & 4 deletions core/src/main/scala/cats/Apply.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cats

import cats.data.NestedApply

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -60,8 +58,8 @@ trait Apply[F[_]] extends Functor[F] with Cartesian[F] with ApplyArityFunctions[
def map2Eval[A, B, Z](fa: F[A], fb: Eval[F[B]])(f: (A, B) => Z): Eval[F[Z]] =
fb.map(fb => map2(fa, fb)(f))

def nest[G[_]: Apply]: Apply[Lambda[A => F[G[A]]]] =
new NestedApply[F, G] {
def compose[G[_]: Apply]: Apply[Lambda[A => F[G[A]]]] =
new ComposedApply[F, G] {
val F = self
val G = Apply[G]
}
Expand Down
131 changes: 131 additions & 0 deletions core/src/main/scala/cats/Composed.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package cats

import cats.functor._

private[cats] trait ComposedInvariant[F[_], G[_]] extends Invariant[Lambda[A => F[G[A]]]] { outer =>
def F: Invariant[F]
def G: Invariant[G]

override def imap[A, B](fga: F[G[A]])(f: A => B)(g: B => A): F[G[B]] =
F.imap(fga)(ga => G.imap(ga)(f)(g))(gb => G.imap(gb)(g)(f))
}

private[cats] trait ComposedFunctor[F[_], G[_]] extends Functor[Lambda[A => F[G[A]]]] with ComposedInvariant[F, G] { outer =>
def F: Functor[F]
def G: Functor[G]

override def map[A, B](fga: F[G[A]])(f: A => B): F[G[B]] =
F.map(fga)(ga => G.map(ga)(f))
}

private[cats] trait ComposedApply[F[_], G[_]] extends Apply[Lambda[A => F[G[A]]]] with ComposedFunctor[F, G] { outer =>
def F: Apply[F]
def G: Apply[G]

override def ap[A, B](fgf: F[G[A => B]])(fga: F[G[A]]): F[G[B]] =
F.ap(F.map(fgf)(gf => G.ap(gf)(_)))(fga)

override def product[A, B](fga: F[G[A]], fgb: F[G[B]]): F[G[(A, B)]] =
F.map2(fga, fgb)(G.product)
}

private[cats] trait ComposedApplicative[F[_], G[_]] extends Applicative[Lambda[A => F[G[A]]]] with ComposedApply[F, G] { outer =>
def F: Applicative[F]
def G: Applicative[G]

override def pure[A](x: A): F[G[A]] = F.pure(G.pure(x))
}

private[cats] trait ComposedSemigroupK[F[_], G[_]] extends SemigroupK[Lambda[A => F[G[A]]]] { outer =>
def F: SemigroupK[F]

override def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = F.combineK(x, y)
}

private[cats] trait ComposedMonoidK[F[_], G[_]] extends MonoidK[Lambda[A => F[G[A]]]] with ComposedSemigroupK[F, G] { outer =>
def F: MonoidK[F]

override def empty[A]: F[G[A]] = F.empty
}

private[cats] trait ComposedAlternative[F[_], G[_]] extends Alternative[Lambda[A => F[G[A]]]] with ComposedApplicative[F, G] with ComposedMonoidK[F, G] { outer =>
def F: Alternative[F]
}

private[cats] trait ComposedFoldable[F[_], G[_]] extends Foldable[Lambda[A => F[G[A]]]] { outer =>
def F: Foldable[F]
def G: Foldable[G]

override def foldLeft[A, B](fga: F[G[A]], b: B)(f: (B, A) => B): B =
F.foldLeft(fga, b)((b, a) => G.foldLeft(a, b)(f))

override def foldRight[A, B](fga: F[G[A]], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
F.foldRight(fga, lb)((ga, lb) => G.foldRight(ga, lb)(f))
}

private[cats] trait ComposedTraverse[F[_], G[_]] extends Traverse[Lambda[A => F[G[A]]]] with ComposedFoldable[F, G] with ComposedFunctor[F, G] { outer =>
def F: Traverse[F]
def G: Traverse[G]

override def traverse[H[_]: Applicative, A, B](fga: F[G[A]])(f: A => H[B]): H[F[G[B]]] =
F.traverse(fga)(ga => G.traverse(ga)(f))
}

private[cats] trait ComposedReducible[F[_], G[_]] extends Reducible[Lambda[A => F[G[A]]]] with ComposedFoldable[F, G] { outer =>
def F: Reducible[F]
def G: Reducible[G]

override def reduceLeftTo[A, B](fga: F[G[A]])(f: A => B)(g: (B, A) => B): B = {
def toB(ga: G[A]): B = G.reduceLeftTo(ga)(f)(g)
F.reduceLeftTo(fga)(toB) { (b, ga) =>
G.foldLeft(ga, b)(g)
}
}

override def reduceRightTo[A, B](fga: F[G[A]])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] = {
def toB(ga: G[A]): B = G.reduceRightTo(ga)(f)(g).value
F.reduceRightTo(fga)(toB) { (ga, lb) =>
G.foldRight(ga, lb)(g)
}
}
}

private[cats] trait ComposedContravariant[F[_], G[_]] extends Functor[Lambda[A => F[G[A]]]] { outer =>
def F: Contravariant[F]
def G: Contravariant[G]

override def map[A, B](fga: F[G[A]])(f: A => B): F[G[B]] =
F.contramap(fga)(gb => G.contramap(gb)(f))
}

private[cats] trait ComposedContravariantCovariant[F[_], G[_]] extends Contravariant[Lambda[A => F[G[A]]]] { outer =>
def F: Contravariant[F]
def G: Functor[G]

override def contramap[A, B](fga: F[G[A]])(f: B => A): F[G[B]] =
F.contramap(fga)(gb => G.map(gb)(f))
}

private[cats] trait ComposedCovariantContravariant[F[_], G[_]] extends Contravariant[Lambda[A => F[G[A]]]] { outer =>
def F: Functor[F]
def G: Contravariant[G]

override def contramap[A, B](fga: F[G[A]])(f: B => A): F[G[B]] =
F.map(fga)(ga => G.contramap(ga)(f))
}

private[cats] trait ComposedInvariantCovariant[F[_], G[_]] extends Invariant[Lambda[A => F[G[A]]]] { outer =>
def F: Invariant[F]
def G: Functor[G]

override def imap[A, B](fga: F[G[A]])(f: A => B)(g: B => A): F[G[B]] =
F.imap(fga)(ga => G.map(ga)(f))(gb => G.map(gb)(g))
}

private[cats] trait ComposedInvariantContravariant[F[_], G[_]] extends Invariant[Lambda[A => F[G[A]]]] { outer =>
def F: Invariant[F]
def G: Contravariant[G]

override def imap[A, B](fga: F[G[A]])(f: A => B)(g: B => A): F[G[B]] =
F.imap(fga)(ga => G.contramap(ga)(g))(gb => G.contramap(gb)(f))
}
5 changes: 2 additions & 3 deletions core/src/main/scala/cats/Foldable.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cats

import cats.data.NestedFoldable
import scala.collection.mutable
import simulacrum.typeclass

Expand Down Expand Up @@ -270,8 +269,8 @@ import simulacrum.typeclass
def nonEmpty[A](fa: F[A]): Boolean =
!isEmpty(fa)

def nest[G[_]: Foldable]: Foldable[Lambda[A => F[G[A]]]] =
new NestedFoldable[F, G] {
def compose[G[_]: Foldable]: Foldable[Lambda[A => F[G[A]]]] =
new ComposedFoldable[F, G] {
val F = self
val G = Foldable[G]
}
Expand Down
9 changes: 4 additions & 5 deletions core/src/main/scala/cats/Functor.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package cats

import cats.data.{NestedCovariantContravariant, NestedFunctor}
import cats.functor.Contravariant

import simulacrum.typeclass
Expand Down Expand Up @@ -40,14 +39,14 @@ import simulacrum.typeclass
*/
def as[A, B](fa: F[A], b: B): F[B] = map(fa)(_ => b)

def nest[G[_]: Functor]: Functor[Lambda[A => F[G[A]]]] =
new NestedFunctor[F, G] {
def compose[G[_]: Functor]: Functor[Lambda[A => F[G[A]]]] =
new ComposedFunctor[F, G] {
val F = self
val G = Functor[G]
}

override def nestContravariant[G[_]: Contravariant]: Contravariant[Lambda[A => F[G[A]]]] =
new NestedCovariantContravariant[F, G] {
override def composeContravariant[G[_]: Contravariant]: Contravariant[Lambda[A => F[G[A]]]] =
new ComposedCovariantContravariant[F, G] {
val F = self
val G = Contravariant[G]
}
Expand Down
6 changes: 2 additions & 4 deletions core/src/main/scala/cats/MonoidK.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cats

import cats.data.NestedMonoidK

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -40,8 +38,8 @@ import simulacrum.typeclass
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}

override def nest[G[_]]: MonoidK[Lambda[A => F[G[A]]]] =
new NestedMonoidK[F, G] {
override def compose[G[_]]: MonoidK[Lambda[A => F[G[A]]]] =
new ComposedMonoidK[F, G] {
val F = self
}
}
6 changes: 2 additions & 4 deletions core/src/main/scala/cats/Reducible.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cats

import cats.data.NestedReducible

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -109,8 +107,8 @@ import simulacrum.typeclass
def sequence1_[G[_], A](fga: F[G[A]])(implicit G: Apply[G]): G[Unit] =
G.map(reduceLeft(fga)((x, y) => G.map2(x, y)((_, b) => b)))(_ => ())

def nest[G[_]: Reducible]: Reducible[Lambda[A => F[G[A]]]] =
new NestedReducible[F, G] {
def compose[G[_]: Reducible]: Reducible[Lambda[A => F[G[A]]]] =
new ComposedReducible[F, G] {
val F = self
val G = Reducible[G]
}
Expand Down
6 changes: 2 additions & 4 deletions core/src/main/scala/cats/SemigroupK.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cats

import cats.data.NestedSemigroupK

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -38,8 +36,8 @@ import simulacrum.typeclass
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}

def nest[G[_]]: SemigroupK[Lambda[A => F[G[A]]]] =
new NestedSemigroupK[F, G] {
def compose[G[_]]: SemigroupK[Lambda[A => F[G[A]]]] =
new ComposedSemigroupK[F, G] {
val F = self
}
}
11 changes: 5 additions & 6 deletions core/src/main/scala/cats/Traverse.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package cats

import cats.data.NestedTraverse

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -51,10 +49,11 @@ import simulacrum.typeclass
def sequenceU[GA](fga: F[GA])(implicit U: Unapply[Applicative,GA]): U.M[F[U.A]] =
traverse(fga)(U.subst)(U.TC)

def nest[G[_]: Traverse]: Traverse[Lambda[A => F[G[A]]]] = new NestedTraverse[F, G] {
val F = self
val G = Traverse[G]
}
def compose[G[_]: Traverse]: Traverse[Lambda[A => F[G[A]]]] =
new ComposedTraverse[F, G] {
val F = self
val G = Traverse[G]
}

override def map[A, B](fa: F[A])(f: A => B): F[B] =
traverse[Id, A, B](fa)(f)
Expand Down
Loading

0 comments on commit 86ce5ed

Please sign in to comment.