Skip to content

Commit

Permalink
Merge pull request #843 from ceedubs/751-followup
Browse files Browse the repository at this point in the history
Followup to #751 (replaces #757)
  • Loading branch information
adelbertc committed Feb 1, 2016
2 parents 7c9c209 + 58b3f5b commit a369fa0
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 17 deletions.
18 changes: 17 additions & 1 deletion core/src/main/scala/cats/Alternative.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,21 @@ package cats

import simulacrum.typeclass

@typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F]
@typeclass trait Alternative[F[_]] extends Applicative[F] with MonoidK[F] { self =>

/**
* Compose this `Alternative` instance with an [[Applicative]] instance.
*/
override def compose[G[_]](implicit GG: Applicative[G]): Alternative[λ[α => F[G[α]]]] =
new CompositeAlternative[F, G] {
implicit def F: Alternative[F] = self
implicit def G: Applicative[G] = GG
}
}

trait CompositeAlternative[F[_], G[_]]
extends Alternative[λ[α => F[G[α]]]] with CompositeApplicative[F, G] with CompositeMonoidK[F, G] {

implicit def F: Alternative[F]
implicit def G: Applicative[G]
}
16 changes: 16 additions & 0 deletions core/src/main/scala/cats/MonoidK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ import simulacrum.typeclass
*/
def empty[A]: F[A]

/**
* Compose this MonoidK with an arbitrary type constructor
*/
override def composeK[G[_]]: MonoidK[λ[α => F[G[α]]]] =
new CompositeMonoidK[F, G] {
implicit def F: MonoidK[F] = self
}

/**
* Given a type A, create a concrete Monoid[F[A]].
*/
Expand All @@ -38,3 +46,11 @@ import simulacrum.typeclass
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}
}

trait CompositeMonoidK[F[_],G[_]]
extends MonoidK[λ[α => F[G[α]]]] with CompositeSemigroupK[F, G] {

implicit def F: MonoidK[F]

def empty[A]: F[G[A]] = F.empty
}
16 changes: 12 additions & 4 deletions core/src/main/scala/cats/SemigroupK.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ import simulacrum.{op, typeclass}
def combineK[A](x: F[A], y: F[A]): F[A]

/**
* Compose two SemigroupK intsances.
* Compose this SemigroupK with an arbitrary type constructor
*/
def compose[G[_]: SemigroupK]: SemigroupK[λ[α => F[G[α]]]] =
new SemigroupK[λ[α => F[G[α]]]] {
def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = self.combineK(x, y)
def composeK[G[_]]: SemigroupK[λ[α => F[G[α]]]] =
new CompositeSemigroupK[F, G] {
implicit def F: SemigroupK[F] = self
}

/**
Expand All @@ -44,3 +44,11 @@ import simulacrum.{op, typeclass}
def combine(x: F[A], y: F[A]): F[A] = self.combineK(x, y)
}
}

trait CompositeSemigroupK[F[_],G[_]]
extends SemigroupK[λ[α => F[G[α]]]] {

implicit def F: SemigroupK[F]

def combineK[A](x: F[G[A]], y: F[G[A]]): F[G[A]] = F.combineK(x, y)
}
1 change: 1 addition & 0 deletions core/src/main/scala/cats/data/OneAnd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ trait OneAndLowPriority1 extends OneAndLowPriority0 {
def map[A, B](fa: OneAnd[F, A])(f: A => B): OneAnd[F, B] =
OneAnd(f(fa.head), F.map(fa.tail)(f))
}

}

trait OneAndLowPriority2 extends OneAndLowPriority1 {
Expand Down
32 changes: 20 additions & 12 deletions tests/src/test/scala/cats/tests/ComposeTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package cats
package tests

import cats.data.{ NonEmptyList, NonEmptyVector, OneAnd }
import cats.laws.discipline.{ ApplicativeTests, FoldableTests, CartesianTests, SemigroupKTests, arbitrary, eq }, arbitrary._, eq._
import cats.laws.discipline.{ AlternativeTests, ApplicativeTests, FoldableTests, CartesianTests, MonoidKTests, SemigroupKTests, arbitrary, eq }, arbitrary._, eq._
import org.scalacheck.Arbitrary

class ComposeTests extends CatsSuite {
Expand All @@ -12,6 +12,15 @@ class ComposeTests extends CatsSuite {
implicit override val generatorDrivenConfig: PropertyCheckConfiguration =
PropertyCheckConfig(maxSize = 5, minSuccessful = 20)

{
// Alternative composition

implicit val alternativeListVector: Alternative[Lambda[A => List[Vector[A]]]] = Alternative[List] compose Alternative[Vector]
implicit val iso = CartesianTests.Isomorphisms.invariant[Lambda[A => List[Vector[A]]]]

checkAll("Alternative[Lambda[A => List[Vector[A]]]]", AlternativeTests[Lambda[A => List[Vector[A]]]].alternative[Int, Int, Int])
}

{
// Applicative composition

Expand All @@ -30,19 +39,18 @@ class ComposeTests extends CatsSuite {
}

{
// Reducible composition
// MonoidK composition

implicit val monoidKListVector: MonoidK[Lambda[A => List[Vector[A]]]] = MonoidK[List].composeK[Vector]

val nelReducible =
new NonEmptyReducible[NonEmptyList, List] {
def split[A](fa: NonEmptyList[A]): (A, List[A]) = (fa.head, fa.tail)
}
checkAll("MonoidK[Lambda[A => List[Vector[A]]]]", MonoidKTests[Lambda[A => List[Vector[A]]]].monoidK[Int])
}

val nevReducible =
new NonEmptyReducible[NonEmptyVector, Vector] {
def split[A](fa: NonEmptyVector[A]): (A, Vector[A]) = (fa.head, fa.tail)
}
{
// Reducible composition

implicit val reducibleListVector: Reducible[Lambda[A => NonEmptyList[NonEmptyVector[A]]]] = nelReducible compose nevReducible
implicit val reducibleListVector: Reducible[Lambda[A => NonEmptyList[NonEmptyVector[A]]]] =
Reducible[NonEmptyList] compose Reducible[NonEmptyVector]

// No Reducible-specific laws, so check the Foldable laws are satisfied
checkAll("Reducible[Lambda[A => List[Vector[A]]]]", FoldableTests[Lambda[A => NonEmptyList[NonEmptyVector[A]]]].foldable[Int, Int])
Expand All @@ -51,7 +59,7 @@ class ComposeTests extends CatsSuite {
{
// SemigroupK composition

implicit val semigroupKListVector: SemigroupK[Lambda[A => List[Vector[A]]]] = SemigroupK[List] compose SemigroupK[Vector]
implicit val semigroupKListVector: SemigroupK[Lambda[A => List[Vector[A]]]] = SemigroupK[List].composeK[Vector]

checkAll("SemigroupK[Lambda[A => List[Vector[A]]]]", SemigroupKTests[Lambda[A => List[Vector[A]]]].semigroupK[Int])
}
Expand Down

0 comments on commit a369fa0

Please sign in to comment.