Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use traits to avoid code duplication in Nested instances #1221

Merged
merged 1 commit into from
Jul 22, 2016
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
246 changes: 110 additions & 136 deletions core/src/main/scala/cats/data/Nested.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,201 +32,175 @@ private[data] sealed abstract class NestedInstances extends NestedInstances1 {
FGA.on(_.value)

implicit def catsDataTraverseForNested[F[_]: Traverse, G[_]: Traverse]: Traverse[Nested[F, G, ?]] =
new Traverse[Nested[F, G, ?]] {
val instance = Traverse[F].compose[G]

def traverse[H[_]: Applicative, A, B](fga: Nested[F, G, A])(f: A => H[B]): H[Nested[F, G, B]] =
Applicative[H].map(instance.traverse(fga.value)(f))(Nested(_))

def foldLeft[A, B](fga: Nested[F, G, A], b: B)(f: (B, A) => B): B =
instance.foldLeft(fga.value, b)(f)

def foldRight[A, B](fga: Nested[F, G, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
instance.foldRight(fga.value, lb)(f)

override def map[A, B](fga: Nested[F, G, A])(f: A => B): Nested[F, G, B] =
Nested(instance.map(fga.value)(f))

override def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))
new NestedTraverse[F, G] {
val FG: Traverse[λ[α => F[G[α]]]] = Traverse[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances1 extends NestedInstances2 {
implicit def catsDataReducibleForNested[F[_]: Reducible, G[_]: Reducible]: Reducible[Nested[F, G, ?]] =
new Reducible[Nested[F, G, ?]] {
val instance = Reducible[F].compose[G]

def reduceLeftTo[A, B](fga: Nested[F, G, A])(f: A => B)(g: (B, A) => B): B =
instance.reduceLeftTo(fga.value)(f)(g)

def reduceRightTo[A, B](fga: Nested[F, G, A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] =
instance.reduceRightTo(fga.value)(f)(g)

def foldLeft[A, B](fga: Nested[F, G, A], b: B)(f: (B, A) => B): B =
instance.foldLeft(fga.value, b)(f)

def foldRight[A, B](fga: Nested[F, G, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
instance.foldRight(fga.value, lb)(f)
new NestedReducible[F, G] {
val FG: Reducible[λ[α => F[G[α]]]] = Reducible[F].compose[G]
}

implicit def catsDataContravariantForNested[F[_]: Contravariant, G[_]: Contravariant]: Functor[Nested[F, G, ?]] =
new Functor[Nested[F, G, ?]] {
val instance = Contravariant[F].compose[G]

def map[A, B](fga: Nested[F, G, A])(f: A => B): Nested[F, G, B] =
Nested(instance.map(fga.value)(f))
new NestedFunctor[F, G] {
val FG: Functor[λ[α => F[G[α]]]] = Contravariant[F].compose[G]
}

}

private[data] sealed abstract class NestedInstances2 extends NestedInstances3 {
implicit def catsDataFoldableForNested[F[_]: Foldable, G[_]: Foldable]: Foldable[Nested[F, G, ?]] =
new Foldable[Nested[F, G, ?]] {
val instance = Foldable[F].compose[G]

def foldLeft[A, B](fga: Nested[F, G, A], b: B)(f: (B, A) => B): B =
instance.foldLeft(fga.value, b)(f)

def foldRight[A, B](fga: Nested[F, G, A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
instance.foldRight(fga.value, lb)(f)
new NestedFoldable[F, G] {
val FG: Foldable[λ[α => F[G[α]]]] = Foldable[F].compose[G]
}


implicit def catsDataContravariantForCovariantNested[F[_]: Contravariant, G[_]: Functor]: Contravariant[Nested[F, G, ?]] =
new Contravariant[Nested[F, G, ?]] {
val instance = Contravariant[F].composeFunctor[G]

def contramap[A, B](fga: Nested[F, G, A])(f: B => A): Nested[F, G, B] =
Nested(instance.contramap(fga.value)(f))
new NestedContravariant[F, G] {
val FG: Contravariant[λ[α => F[G[α]]]] = Contravariant[F].composeFunctor[G]
}
}

private[data] sealed abstract class NestedInstances3 extends NestedInstances4 {
implicit def catsDataAlternativeForNested[F[_]: Alternative, G[_]: Applicative]: Alternative[Nested[F, G, ?]] =
new Alternative[Nested[F, G, ?]] {
val instance = Alternative[F].compose[G]

override def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))

override def map[A, B](fga: Nested[F, G, A])(f: A => B): Nested[F, G, B] =
Nested(instance.map(fga.value)(f))

def ap[A, B](fgf: Nested[F, G, A => B])(fga: Nested[F, G, A]): Nested[F, G, B] =
Nested(instance.ap(fgf.value)(fga.value))

override def product[A, B](fga: Nested[F, G, A], fgb: Nested[F, G, B]): Nested[F, G, (A, B)] =
Nested(instance.product(fga.value, fgb.value))

def pure[A](x: A): Nested[F, G, A] = Nested(instance.pure(x))

def combineK[A](x: Nested[F, G, A], y: Nested[F, G, A]): Nested[F, G, A] = Nested(instance.combineK(x.value, y.value))

def empty[A]: Nested[F, G, A] = Nested(instance.empty[A])
new NestedAlternative[F, G] {
val FG: Alternative[λ[α => F[G[α]]]] = Alternative[F].compose[G]
}

implicit def catsDataContravariantForContravariantNested[F[_]: Functor, G[_]: Contravariant]: Contravariant[Nested[F, G, ?]] =
new Contravariant[Nested[F, G, ?]] {
val instance = Functor[F].composeContravariant[G]

def contramap[A, B](fga: Nested[F, G, A])(f: B => A): Nested[F, G, B] =
Nested(instance.contramap(fga.value)(f))
new NestedContravariant[F, G] {
val FG: Contravariant[λ[α => F[G[α]]]] = Functor[F].composeContravariant[G]
}
}

private[data] sealed abstract class NestedInstances4 extends NestedInstances5 {
implicit def catsDataApplicativeForNested[F[_]: Applicative, G[_]: Applicative]: Applicative[Nested[F, G, ?]] =
new Applicative[Nested[F, G, ?]] {
val instance = Applicative[F].compose[G]

override def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))

override def map[A, B](fga: Nested[F, G, A])(f: A => B): Nested[F, G, B] =
Nested(instance.map(fga.value)(f))

def ap[A, B](fgf: Nested[F, G, A => B])(fga: Nested[F, G, A]): Nested[F, G, B] =
Nested(instance.ap(fgf.value)(fga.value))

override def product[A, B](fga: Nested[F, G, A], fgb: Nested[F, G, B]): Nested[F, G, (A, B)] =
Nested(instance.product(fga.value, fgb.value))

def pure[A](x: A): Nested[F, G, A] = Nested(instance.pure(x))
new NestedApplicative[F, G] {
val FG: Applicative[λ[α => F[G[α]]]] = Applicative[F].compose[G]
}

implicit def catsDataMonoidKForNested[F[_]: MonoidK, G[_]]: MonoidK[Nested[F, G, ?]] =
new MonoidK[Nested[F, G, ?]] {
val instance = MonoidK[F].compose[G]

def combineK[A](x: Nested[F, G, A], y: Nested[F, G, A]): Nested[F, G, A] = Nested(instance.combineK(x.value, y.value))

def empty[A]: Nested[F, G, A] = Nested(instance.empty[A])
new NestedMonoidK[F, G] {
val FG: MonoidK[λ[α => F[G[α]]]] = MonoidK[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances5 extends NestedInstances6 {
implicit def catsDataApplyForNested[F[_]: Apply, G[_]: Apply]: Apply[Nested[F, G, ?]] =
new Apply[Nested[F, G, ?]] {
val instance = Apply[F].compose[G]

def ap[A, B](fgf: Nested[F, G, A => B])(fga: Nested[F, G, A]): Nested[F, G, B] =
Nested(instance.ap(fgf.value)(fga.value))

override def product[A, B](fga: Nested[F, G, A], fgb: Nested[F, G, B]): Nested[F, G, (A, B)] =
Nested(instance.product(fga.value, fgb.value))

def map[A, B](fga: Nested[F, G, A])(f: A => B): Nested[F, G, B] =
Nested(instance.map(fga.value)(f))
new NestedApply[F, G] {
val FG: Apply[λ[α => F[G[α]]]] = Apply[F].compose[G]
}

implicit def catsDataSemigroupKForNested[F[_]: SemigroupK, G[_]]: SemigroupK[Nested[F, G, ?]] =
new SemigroupK[Nested[F, G, ?]] {
val instance = SemigroupK[F].compose[G]

def combineK[A](x: Nested[F, G, A], y: Nested[F, G, A]): Nested[F, G, A] = Nested(instance.combineK(x.value, y.value))
new NestedSemigroupK[F, G] {
val FG: SemigroupK[λ[α => F[G[α]]]] = SemigroupK[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances6 extends NestedInstances7 {
implicit def catsDataFunctorForNested[F[_]: Functor, G[_]: Functor]: Functor[Nested[F, G, ?]] =
new Functor[Nested[F, G, ?]] {
val instance = Functor[F].compose[G]

def map[A, B](fga: Nested[F, G, A])(f: A => B): Nested[F, G, B] =
Nested(instance.map(fga.value)(f))

override def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))
new NestedFunctor[F, G] {
val FG: Functor[λ[α => F[G[α]]]] = Functor[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances7 extends NestedInstances8 {
implicit def catsDataInvariantForNested[F[_]: Invariant, G[_]: Invariant]: Invariant[Nested[F, G, ?]] =
new Invariant[Nested[F, G, ?]] {
val instance = Invariant[F].compose[G]

def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))
new NestedInvariant[F, G] {
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].compose[G]
}
}

private[data] sealed abstract class NestedInstances8 extends NestedInstances9 {
implicit def catsDataInvariantForCovariantNested[F[_]: Invariant, G[_]: Functor]: Invariant[Nested[F, G, ?]] =
new Invariant[Nested[F, G, ?]] {
val instance = Invariant[F].composeFunctor[G]

def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))
new NestedInvariant[F, G] {
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeFunctor[G]
}
}

private[data] sealed abstract class NestedInstances9 {
implicit def catsDataInvariantForNestedContravariant[F[_]: Invariant, G[_]: Contravariant]: Invariant[Nested[F, G, ?]] =
new Invariant[Nested[F, G, ?]] {
val instance = Invariant[F].composeContravariant[G]

def imap[A, B](fga: Nested[F, G, A])(f: A => B)(g: B => A): Nested[F, G, B] =
Nested(instance.imap(fga.value)(f)(g))
new NestedInvariant[F, G] {
val FG: Invariant[λ[α => F[G[α]]]] = Invariant[F].composeContravariant[G]
}
}

private[data] trait NestedInvariant[F[_], G[_]] extends Invariant[Nested[F, G, ?]] {
def FG: Invariant[λ[α => F[G[α]]]]

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

private[data] trait NestedFunctor[F[_], G[_]] extends Functor[Nested[F, G, ?]] with NestedInvariant[F, G] {
override def FG: Functor[λ[α => F[G[α]]]]

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

private[data] trait NestedApply[F[_], G[_]] extends Apply[Nested[F, G, ?]] with NestedFunctor[F, G] {
override def FG: Apply[λ[α => F[G[α]]]]

override def ap[A, B](fgf: Nested[F, G, A => B])(fga: Nested[F, G, A]): Nested[F, G, B] =
Nested(FG.ap(fgf.value)(fga.value))

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

private[data] trait NestedApplicative[F[_], G[_]] extends Applicative[Nested[F, G, ?]] with NestedApply[F, G] {
def FG: Applicative[λ[α => F[G[α]]]]

def pure[A](x: A): Nested[F, G, A] = Nested(FG.pure(x))
}

private[data] trait NestedSemigroupK[F[_], G[_]] extends SemigroupK[Nested[F, G, ?]] {
def FG: SemigroupK[λ[α => F[G[α]]]]

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

private[data] trait NestedMonoidK[F[_], G[_]] extends MonoidK[Nested[F, G, ?]] with NestedSemigroupK[F, G] {
def FG: MonoidK[λ[α => F[G[α]]]]

def empty[A]: Nested[F, G, A] = Nested(FG.empty[A])
}

private[data] trait NestedAlternative[F[_], G[_]] extends Alternative[Nested[F, G, ?]] with NestedApplicative[F, G] with NestedMonoidK[F, G] {
def FG: Alternative[λ[α => F[G[α]]]]
}

private[data] trait NestedFoldable[F[_], G[_]] extends Foldable[Nested[F, G, ?]] {
def FG: Foldable[λ[α => F[G[α]]]]

def foldLeft[A, B](fga: Nested[F, G, A], b: B)(f: (B, A) => B): B =
FG.foldLeft(fga.value, b)(f)

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

private[data] trait NestedTraverse[F[_], G[_]] extends Traverse[Nested[F, G, ?]] with NestedFoldable[F, G] with NestedFunctor[F, G] {
def FG: Traverse[λ[α => F[G[α]]]]

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

private[data] trait NestedReducible[F[_], G[_]] extends Reducible[Nested[F, G, ?]] with NestedFoldable[F, G] {
def FG: Reducible[λ[α => F[G[α]]]]

def reduceLeftTo[A, B](fga: Nested[F, G, A])(f: A => B)(g: (B, A) => B): B =
FG.reduceLeftTo(fga.value)(f)(g)

def reduceRightTo[A, B](fga: Nested[F, G, A])(f: A => B)(g: (A, Eval[B]) => Eval[B]): Eval[B] =
FG.reduceRightTo(fga.value)(f)(g)
}

private[data] trait NestedContravariant[F[_], G[_]] extends Contravariant[Nested[F, G, ?]] {
def FG: Contravariant[λ[α => F[G[α]]]]

def contramap[A, B](fga: Nested[F, G, A])(f: B => A): Nested[F, G, B] =
Nested(FG.contramap(fga.value)(f))
}