Skip to content

Instantly share code, notes, and snippets.

@ahjohannessen
Forked from SystemFw/Ex.scala
Created October 29, 2018 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ahjohannessen/bbb910bdc389691bf4b8419e7526f3fc to your computer and use it in GitHub Desktop.
Save ahjohannessen/bbb910bdc389691bf4b8419e7526f3fc to your computer and use it in GitHub Desktop.
Get instances of a typeclass `TC[_]` for all cases of a Coproduct [shapeless]
import shapeless._
@annotation.implicitNotFound("Make sure all cases of ${C} have an instance of ${TC}")
trait CopTCs[C <: Coproduct, TC[_]] {
type Out <: HList
def result: Out
}
object CopTCs {
type Aux[C <: Coproduct, TC[_], O <: HList] = CopTCs[C, TC] { type Out = O }
def apply[C <: Coproduct, TC[_]](implicit ev: CopTCs[C, TC]) = ev
implicit def cnil[TC[_]]: CopTCs.Aux[CNil, TC, HNil] = new CopTCs[CNil, TC] {
type Out = HNil
def result = HNil
}
implicit def ccons[TC[_], L, R <: Coproduct, O <: HList](implicit ev: TC[L], rest: CopTCs.Aux[R, TC, O]): CopTCs.Aux[L :+: R, TC, TC[L] :: O] = new CopTCs[L :+: R, TC] {
type Out = TC[L] :: O
def result = ev :: rest.result
}
}
object Ex {
import cats._, implicits._
type Monoids = Int :+: String :+: CNil
type Nope
type NotMonoids = Nope :+: Monoids
def instances = CopTCs[Monoids, Monoid].result
// res0: CopTCs[Ex.Monoids,cats.Monoid]#Out = cats.kernel.instances.IntGroup@69aba755 :: cats.kernel.instances.StringMonoid@981dd7c :: HNil
def compilationError = CopTCs[NotMonoids, Monoid].result
// Make sure all cases of Ex.NotMonoids have an instance of cats.Monoid
// [error] def compilationError = CopTCs[NotMonoids, Monoid].result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment