Skip to content

Instantly share code, notes, and snippets.

@SystemFw
Created October 26, 2018 20:39
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save SystemFw/7d14724e8cdb560b62136d3d3dbc305f to your computer and use it in GitHub Desktop.
Save SystemFw/7d14724e8cdb560b62136d3d3dbc305f 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