I have a relatively ergonomic pattern I use to pattern match shapeless Coproducts. It looks basically like this
val stringOrInt: String :+: Int :+: CNil = Coproduct("Hello world")
implicit class Coproduct2Syntax[A, B](val value: A :+: B :+: CNil) extends AnyVal {
type cop = A :+: B :+: CNil
def comatch[Z](
caseA: PartialFunction[A, Z],
caseB: PartialFunction[B, Z]
): Z = {
val a = Function.unlift[cop, Z](_.select[A].flatMap(caseA.lift))
val b = Function.unlift[cop, Z](_.select[B].flatMap(caseB.lift))
a.orElse(b).apply(value)
}
}
stringOrInt.comatch({
case s => s.length
},{
case i => i
})
// Int = 11
This works well enough but I haven't gone through the trouble of defining CoproductNSyntax for 0-22.
I'm aware we can do something similar with Poly1, but that requires defining a separate object
My question is: are there any existing libraries that provide this type of pattern for matching for Coproducts?