Skip to content

Commit

Permalink
Add nest methods to type classes
Browse files Browse the repository at this point in the history
Nested instances are no longer wrapped in Nested, but have a toNested
method to allow code sharing between the unwrapped and wrapped instances.
  • Loading branch information
adelbertc committed May 21, 2016
1 parent 44b065c commit 83ea1ce
Show file tree
Hide file tree
Showing 12 changed files with 310 additions and 64 deletions.
10 changes: 9 additions & 1 deletion core/src/main/scala/cats/Alternative.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
package cats

import cats.data.NestedAlternative

import simulacrum.typeclass

@typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F]
@typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F] { self =>
def nestApplicative[G[_]: Applicative]: Alternative[Lambda[A => F[G[A]]]] =
new NestedAlternative[F, G] {
val F = self
val G = Applicative[G]
}
}
9 changes: 8 additions & 1 deletion core/src/main/scala/cats/Applicative.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package cats

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

/**
* Applicative functor.
Expand Down Expand Up @@ -43,4 +44,10 @@ import cats.std.list._

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] {
val F = self
val G = Applicative[G]
}
}
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/Apply.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cats

import cats.data.NestedApply

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -57,4 +59,10 @@ 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] {
val F = self
val G = Apply[G]
}
}
7 changes: 7 additions & 0 deletions core/src/main/scala/cats/Foldable.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package cats

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

Expand Down Expand Up @@ -268,6 +269,12 @@ 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] {
val F = self
val G = Foldable[G]
}
}

object Foldable {
Expand Down
15 changes: 15 additions & 0 deletions core/src/main/scala/cats/Functor.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package cats

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

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -36,4 +39,16 @@ import simulacrum.typeclass
* Replaces the `A` value in `F[A]` with the supplied value.
*/
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] {
val F = self
val G = Functor[G]
}

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

import cats.data.NestedMonoidK

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -37,4 +39,9 @@ import simulacrum.typeclass
def empty: F[A] = self.empty
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] {
val F = self
}
}
8 changes: 8 additions & 0 deletions core/src/main/scala/cats/Reducible.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cats

import cats.data.NestedReducible

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -106,6 +108,12 @@ 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] {
val F = self
val G = Reducible[G]
}
}

/**
Expand Down
7 changes: 7 additions & 0 deletions core/src/main/scala/cats/SemigroupK.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cats

import cats.data.NestedSemigroupK

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -35,4 +37,9 @@ import simulacrum.typeclass
new Semigroup[F[A]] {
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] {
val F = self
}
}
7 changes: 7 additions & 0 deletions core/src/main/scala/cats/Traverse.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cats

import cats.data.NestedTraverse

import simulacrum.typeclass

/**
Expand Down Expand Up @@ -49,6 +51,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]
}

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

0 comments on commit 83ea1ce

Please # to comment.