Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Benefit of Coproduct over `sealed trait`?

I read the following about coproducts in the excellent Shapeless Guide:

... it’s worth stating that Coproducts aren’t particularly special. The functionality above can be achieved using Either and Nothing in place of :+: and CNil.

Here's the above code:

import shapeless.{Coproduct, :+:, CNil, Inl, Inr}
case class Red()
case class Amber()
case class Green()
type Light = Red :+: Amber :+: Green :+: CNil

val red: Light = Inl(Red())
// red: Light = Inl(Red())
val green: Light = Inr(Inr(Inl(Green())))
// green: Light = Inr(Inr(Inl(Green())))

For my own understanding, what is the benefit, if any, of using a Coproduct over a sealed trait?

like image 519
Kevin Meredith Avatar asked Jan 31 '17 03:01

Kevin Meredith


2 Answers

One benefit is similar to that of using type classes rather than inheritance: ad-hoc polymorphism. You can make a Coproduct out of any types, even those outside of your control, e.g. String and Int. You can't do that with a sealed trait (unless you made awkward StringHolder and IntHolder case classes to wrap them).

like image 190
Chris B Avatar answered Nov 11 '22 11:11

Chris B


Same as the benefit of using HList over a case class: you can write generic code which works for all coproducts, or all coproducts which satisfy some condition. And then use Generic to make the same code work with sealed traits as well.

like image 33
Alexey Romanov Avatar answered Nov 11 '22 11:11

Alexey Romanov