Skip to content

Commit

Permalink
Version-specific semiauto
Browse files Browse the repository at this point in the history
  • Loading branch information
joroKr21 committed Apr 21, 2020
1 parent c396810 commit 18fa6bb
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 126 deletions.
34 changes: 34 additions & 0 deletions core/src/main/scala-2.11/cats/derived/semiauto.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cats.derived

/**
* allows semi automatically derive each instance. The derivation might need help when
* there are fields with type constructor that comes with instances
* e.g.
* {{{
* scala> case class Foo(bars: List[Bar])
* scala> case class Bar(a: String)
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res1: String = Foo(bars = $colon$colon(head = Bar(a = a), tl$access$1 = Nil.type()))
* }}}
* Note that semi.show didn't respect the native `Show[List]` instance
*
* You could either derive a Bar instance first
* {{{
* scala> implicit val barShow = cats.derived.semi.show[Bar]
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res2: String = Foo(bars = List(Bar(a = a)))
* }}}
*
* Or you can take advantage of a controlled auto derivation
* {{{
* scala> implicit val fooShow: Show[Foo] = { |
* import cats.derived.auto.show._ |
* cats.derived.semiauto.show |
* }
* scala> Foo(List(Bar("a"))).show
* res3: String = Foo(bars = List(Bar(a = a)))
* }}}
*/
object semiauto extends SemiAutoInstances
34 changes: 34 additions & 0 deletions core/src/main/scala-2.12/cats/derived/semiauto.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cats.derived

/**
* allows semi automatically derive each instance. The derivation might need help when
* there are fields with type constructor that comes with instances
* e.g.
* {{{
* scala> case class Foo(bars: List[Bar])
* scala> case class Bar(a: String)
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res1: String = Foo(bars = $colon$colon(head = Bar(a = a), tl$access$1 = Nil.type()))
* }}}
* Note that semi.show didn't respect the native `Show[List]` instance
*
* You could either derive a Bar instance first
* {{{
* scala> implicit val barShow = cats.derived.semi.show[Bar]
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res2: String = Foo(bars = List(Bar(a = a)))
* }}}
*
* Or you can take advantage of a controlled auto derivation
* {{{
* scala> implicit val fooShow: Show[Foo] = { |
* import cats.derived.auto.show._ |
* cats.derived.semiauto.show |
* }
* scala> Foo(List(Bar("a"))).show
* res3: String = Foo(bars = List(Bar(a = a)))
* }}}
*/
object semiauto extends SemiAutoInstances
73 changes: 73 additions & 0 deletions core/src/main/scala-2.13/cats/derived/semiauto.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package cats
package derived

import alleycats.{ConsK, Empty, EmptyK, Pure}
import cats.kernel.{CommutativeMonoid, CommutativeSemigroup}

/**
* allows semi automatically derive each instance. The derivation might need help when
* there are fields with type constructor that comes with instances
* e.g.
* {{{
* scala> case class Foo(bars: List[Bar])
* scala> case class Bar(a: String)
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res1: String = Foo(bars = $colon$colon(head = Bar(a = a), tl$access$1 = Nil.type()))
* }}}
* Note that semi.show didn't respect the native `Show[List]` instance
*
* You could either derive a Bar instance first
* {{{
* scala> implicit val barShow = cats.derived.semi.show[Bar]
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res2: String = Foo(bars = List(Bar(a = a)))
* }}}
*
* Or you can take advantage of a controlled auto derivation
* {{{
* scala> implicit val fooShow: Show[Foo] = { |
* import cats.derived.auto.show._ |
* cats.derived.semiauto.show |
* }
* scala> Foo(List(Bar("a"))).show
* res3: String = Foo(bars = List(Bar(a = a)))
* }}}
*/
object semiauto {

def eq[A](implicit ev: MkEq[A]): Eq[A] = ev
def partialOrder[A](implicit ev: MkPartialOrder[A]): PartialOrder[A] = ev
def order[A](implicit ev: MkOrder[A]): Order[A] = ev
def hash[A](implicit ev: MkHash[A]): Hash[A] = ev

def show[A](implicit ev: MkShow[A]): Show[A] = ev
def showPretty[A](implicit ev: MkShowPretty[A]): ShowPretty[A] = ev

def empty[A](implicit ev: MkEmpty[A]): Empty[A] = ev
def emptyK[F[_]](implicit F: MkEmptyK[F]): EmptyK[F] = F

def semigroup[T](implicit ev: MkSemigroup[T]): Semigroup[T] = ev
def semigroupK[F[_]](implicit F: MkSemigroupK[F]): SemigroupK[F] = F
def commutativeSemigroup[T](implicit ev: MkCommutativeSemigroup[T]): CommutativeSemigroup[T] = ev

def monoid[A](implicit ev: MkMonoid[A]): Monoid[A] = ev
def monoidK[F[_]](implicit F: MkMonoidK[F]): MonoidK[F] = F
def commutativeMonoid[A](implicit ev: MkCommutativeMonoid[A]): CommutativeMonoid[A] = ev

def functor[F[_]](implicit F: MkFunctor[F]): Functor[F] = F
def contravariant[F[_]](implicit F: MkContravariant[F]): Contravariant[F] = F
def invariant[F[_]](implicit F: MkInvariant[F]): Invariant[F] = F
def pure[F[_]](implicit F: MkPure[F]): Pure[F] = F
def apply[F[_]](implicit F: MkApply[F]): Apply[F] = F
def applicative[F[_]](implicit F: MkApplicative[F]): Applicative[F] = F

def foldable[F[_]](implicit F: MkFoldable[F]): Foldable[F] = F
def reducible[F[_]](implicit F: MkReducible[F]): Reducible[F] = F
def traverse[F[_]](implicit F: MkTraverse[F]): Traverse[F] = F
def nonEmptyTraverse[F[_]](implicit F: MkNonEmptyTraverse[F]): NonEmptyTraverse[F] = F

def consK[F[_]](implicit F: MkConsK[F, F]): ConsK[F] = MkConsK.consK(F)
def iterable[F[_], A](fa: F[A])(implicit F: MkIterable[F]): Iterable[A] = F.iterable(fa)
}
160 changes: 40 additions & 120 deletions core/src/main/scala/cats/derived/package.scala
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package cats
package derived

import cats.kernel.{CommutativeMonoid, CommutativeSemigroup}
import alleycats._
import cats.derived.util.VersionSpecific.Lazy
import cats.kernel.{CommutativeMonoid, CommutativeSemigroup}
import shapeless.{Cached, Refute}
import util.VersionSpecific.Lazy

/**
* Fully automatically derive the instance, note that this derivation is not cached, so it
Expand Down Expand Up @@ -327,6 +327,43 @@ object cached {
}
}

private[derived] abstract class SemiAutoInstances {

def eq[A](implicit ev: Lazy[MkEq[A]]): Eq[A] = ev.value
def partialOrder[A](implicit ev: Lazy[MkPartialOrder[A]]): PartialOrder[A] = ev.value
def order[A](implicit ev: Lazy[MkOrder[A]]): Order[A] = ev.value
def hash[A](implicit ev: Lazy[MkHash[A]]): Hash[A] = ev.value

def show[A](implicit ev: Lazy[MkShow[A]]): Show[A] = ev.value
def showPretty[A](implicit ev: Lazy[MkShowPretty[A]]): ShowPretty[A] = ev.value

def empty[A](implicit ev: Lazy[MkEmpty[A]]): Empty[A] = ev.value
def emptyK[F[_]](implicit F: Lazy[MkEmptyK[F]]): EmptyK[F] = F.value

def semigroup[T](implicit ev: Lazy[MkSemigroup[T]]): Semigroup[T] = ev.value
def semigroupK[F[_]](implicit F: Lazy[MkSemigroupK[F]]): SemigroupK[F] = F.value
def commutativeSemigroup[T](implicit ev: Lazy[MkCommutativeSemigroup[T]]): CommutativeSemigroup[T] = ev.value

def monoid[A](implicit ev: Lazy[MkMonoid[A]]): Monoid[A] = ev.value
def monoidK[F[_]](implicit F: Lazy[MkMonoidK[F]]): MonoidK[F] = F.value
def commutativeMonoid[A](implicit ev: Lazy[MkCommutativeMonoid[A]]): CommutativeMonoid[A] = ev.value

def functor[F[_]](implicit F: Lazy[MkFunctor[F]]): Functor[F] = F.value
def contravariant[F[_]](implicit F: Lazy[MkContravariant[F]]): Contravariant[F] = F.value
def invariant[F[_]](implicit F: Lazy[MkInvariant[F]]): Invariant[F] = F.value
def pure[F[_]](implicit F: Lazy[MkPure[F]]): Pure[F] = F.value
def apply[F[_]](implicit F: Lazy[MkApply[F]]): Apply[F] = F.value
def applicative[F[_]](implicit F: Lazy[MkApplicative[F]]): Applicative[F] = F.value

def foldable[F[_]](implicit F: Lazy[MkFoldable[F]]): Foldable[F] = F.value
def reducible[F[_]](implicit F: Lazy[MkReducible[F]]): Reducible[F] = F.value
def traverse[F[_]](implicit F: Lazy[MkTraverse[F]]): Traverse[F] = F.value
def nonEmptyTraverse[F[_]](implicit F: Lazy[MkNonEmptyTraverse[F]]): NonEmptyTraverse[F] = F.value

def consK[F[_]](implicit F: Lazy[MkConsK[F, F]]): ConsK[F] = MkConsK.consK(F.value)
def iterable[F[_], A](fa: F[A])(implicit F: MkIterable[F]): Iterable[A] = F.iterable(fa)
}

/**
* allows semi automatically derive each instance. The derivation might need help when
* there are fields with type constructor that comes with instances
Expand Down Expand Up @@ -359,121 +396,4 @@ object cached {
* }}}
*/
@deprecated(message = "Use semiauto instead.", since = "2.1.0")
object semi {

def empty[A](implicit ev: Lazy[MkEmpty[A]]): Empty[A] = ev.value

def emptyK[F[_]](implicit F: Lazy[MkEmptyK[F]]): EmptyK[F] = F.value

def eq[A](implicit ev: Lazy[MkEq[A]]): Eq[A] = ev.value

def partialOrder[A](implicit ev: Lazy[MkPartialOrder[A]]): PartialOrder[A] = ev.value

def order[A](implicit ev: Lazy[MkOrder[A]]): Order[A] = ev.value

def hash[A](implicit ev: Lazy[MkHash[A]]): Hash[A] = ev.value

def contravariant[F[_]](implicit F: Lazy[MkContravariant[F]]): Contravariant[F] = F.value

def functor[F[_]](implicit F: Lazy[MkFunctor[F]]): Functor[F] = F.value

def apply[F[_]](implicit F: Lazy[MkApply[F]]): Apply[F] = F.value

def applicative[F[_]](implicit F: Lazy[MkApplicative[F]]): Applicative[F] = F.value

def show[A](implicit ev: Lazy[MkShow[A]]): Show[A] = ev.value

def showPretty[A](implicit ev: Lazy[MkShowPretty[A]]): ShowPretty[A] = ev.value

def foldable[F[_]](implicit F: Lazy[MkFoldable[F]]): Foldable[F] = F.value

def reducible[F[_]](implicit F: Lazy[MkReducible[F]]): Reducible[F] = F.value

def traverse[F[_]](implicit F: Lazy[MkTraverse[F]]): Traverse[F] = F.value

def nonEmptyTraverse[F[_]](implicit F: Lazy[MkNonEmptyTraverse[F]]): NonEmptyTraverse[F] = F.value

def monoid[A](implicit ev: Lazy[MkMonoid[A]]): Monoid[A] = ev.value

def commutativeMonoid[A](implicit ev: Lazy[MkCommutativeMonoid[A]]): CommutativeMonoid[A] = ev.value

def monoidK[F[_]](implicit F: Lazy[MkMonoidK[F]]): MonoidK[F] = F.value

def pure[F[_]](implicit F: Lazy[MkPure[F]]): Pure[F] = F.value

def semigroup[T](implicit ev: Lazy[MkSemigroup[T]]): Semigroup[T] = ev.value

def commutativeSemigroup[T](implicit ev: Lazy[MkCommutativeSemigroup[T]]): CommutativeSemigroup[T] = ev.value

def semigroupK[F[_]](implicit F: Lazy[MkSemigroupK[F]]): SemigroupK[F] = F.value

def consK[F[_]](implicit F: Lazy[MkConsK[F, F]]): ConsK[F] = MkConsK.consK(F.value)

def iterable[F[_], A](fa: F[A])(implicit F: MkIterable[F]): Iterable[A] = F.iterable(fa)

def invariant[F[_]](implicit F: Lazy[MkInvariant[F]]): Invariant[F] = F.value
}

/**
* allows semi automatically derive each instance. The derivation might need help when
* there are fields with type constructor that comes with instances
* e.g.
* {{{
* scala> case class Foo(bars: List[Bar])
* scala> case class Bar(a: String)
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res1: String = Foo(bars = $colon$colon(head = Bar(a = a), tl$access$1 = Nil.type()))
* }}}
* Note that semi.show didn't respect the native `Show[List]` instance
*
* You could either derive a Bar instance first
* {{{
* scala> implicit val barShow = cats.derived.semi.show[Bar]
*
* scala> cats.derived.semiauto.show[Foo].show(Foo(List(Bar("a"))))
* res2: String = Foo(bars = List(Bar(a = a)))
* }}}
*
* Or you can take advantage of a controlled auto derivation
* {{{
* scala> implicit val fooShow: Show[Foo] = { |
* import cats.derived.auto.show._ |
* cats.derived.semiauto.show |
* }
* scala> Foo(List(Bar("a"))).show
* res3: String = Foo(bars = List(Bar(a = a)))
* }}}
*/
object semiauto {

def eq[A](implicit ev: MkEq[A]): Eq[A] = ev
def partialOrder[A](implicit ev: MkPartialOrder[A]): PartialOrder[A] = ev
def order[A](implicit ev: MkOrder[A]): Order[A] = ev
def hash[A](implicit ev: MkHash[A]): Hash[A] = ev

def show[A](implicit ev: MkShow[A]): Show[A] = ev
def showPretty[A](implicit ev: MkShowPretty[A]): ShowPretty[A] = ev

def empty[A](implicit ev: MkEmpty[A]): Empty[A] = ev
def emptyK[F[_]](implicit F: MkEmptyK[F]): EmptyK[F] = F
def semigroup[T](implicit ev: MkSemigroup[T]): Semigroup[T] = ev
def semigroupK[F[_]](implicit F: MkSemigroupK[F]): SemigroupK[F] = F
def monoid[A](implicit ev: MkMonoid[A]): Monoid[A] = ev
def monoidK[F[_]](implicit F: MkMonoidK[F]): MonoidK[F] = F

def functor[F[_]](implicit F: MkFunctor[F]): Functor[F] = F
def contravariant[F[_]](implicit F: MkContravariant[F]): Contravariant[F] = F
def invariant[F[_]](implicit F: MkInvariant[F]): Invariant[F] = F
def pure[F[_]](implicit F: MkPure[F]): Pure[F] = F
def apply[F[_]](implicit F: MkApply[F]): Apply[F] = F
def applicative[F[_]](implicit F: MkApplicative[F]): Applicative[F] = F

def foldable[F[_]](implicit F: MkFoldable[F]): Foldable[F] = F
def reducible[F[_]](implicit F: MkReducible[F]): Reducible[F] = F
def traverse[F[_]](implicit F: MkTraverse[F]): Traverse[F] = F
def nonEmptyTraverse[F[_]](implicit F: MkNonEmptyTraverse[F]): NonEmptyTraverse[F] = F

def consK[F[_]](implicit F: MkConsK[F, F]): ConsK[F] = MkConsK.consK(F)
def iterable[F[_], A](fa: F[A])(implicit F: MkIterable[F]): Iterable[A] = F.iterable(fa)
}
object semi extends SemiAutoInstances
6 changes: 3 additions & 3 deletions core/src/test/scala/cats/derived/commutativeMonoid.scala
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ class CommutativeMonoidSuite extends KittensSuite {
}

{
implicit val foo: CommutativeMonoid[CommutativeFoo] = semi.commutativeMonoid
implicit lazy val recursive: CommutativeMonoid[Recursive] = semi.commutativeMonoid
implicit val box: CommutativeMonoid[Box[Mul]] = semi.commutativeMonoid
implicit val foo: CommutativeMonoid[CommutativeFoo] = semiauto.commutativeMonoid
implicit lazy val recursive: CommutativeMonoid[Recursive] = semiauto.commutativeMonoid
implicit val box: CommutativeMonoid[Box[Mul]] = semiauto.commutativeMonoid
testCommutativeMonoid("semi")
}
}
Expand Down
6 changes: 3 additions & 3 deletions core/src/test/scala/cats/derived/commutativeSemigroup.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class CommutativeSemigroupSuite extends KittensSuite {
}

{
implicit val foo: CommutativeSemigroup[CommutativeFoo] = semi.commutativeSemigroup
implicit lazy val recursive: CommutativeSemigroup[Recursive] = semi.commutativeSemigroup
implicit val box: CommutativeSemigroup[Box[Mul]] = semi.commutativeSemigroup
implicit val foo: CommutativeSemigroup[CommutativeFoo] = semiauto.commutativeSemigroup
implicit lazy val recursive: CommutativeSemigroup[Recursive] = semiauto.commutativeSemigroup
implicit val box: CommutativeSemigroup[Box[Mul]] = semiauto.commutativeSemigroup
testCommutativeSemigroup("semi")
}
}
Expand Down

0 comments on commit 18fa6bb

Please sign in to comment.