`Coproduct` 相对于 `sealed trait` 的优势是什么?

5

我在优秀的Shapeless指南链接中读到了关于余积类型的以下内容:

... 值得说明的是,余积类型并不特别。可以使用Either和Nothing代替:+和CNil来实现上述功能。

以下是上述代码:

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())))

为了我自己的理解,使用Coproduct相对于使用sealed trait有什么好处(如果有的话)?


当我想要隐藏实现的 case classes 时,我使用 sealed trait。例如,将实现类放在伴生对象中并使它们私有化。在类型系统中混乱没有任何意义。 - Fried Brice
此外,Red是否扩展了Light?使用sealed trait可以实现。如果想避免层次结构,似乎可以使用:+:。 - Fried Brice
2个回答

6

其中一个好处类似于使用类型类而不是继承:即特技多态。您可以将任何类型(包括那些无法控制的类型,例如String和Int)组合成Coproduct。使用密封特质无法做到这一点(除非您使用笨拙的StringHolderIntHolder案例类来包装它们)。


2
与使用case class相比,使用HList的好处是:您可以编写适用于所有余产品或满足某些条件的所有余产品的通用代码。然后使用Generic使同一代码也适用于sealed trait。请注意保留HTML标记。

但是,我不能使用Generic[A]来获取任何情况类的HList吗?其中A是情况类。 - Kevin Meredith
是的,没错。将 Generic[A] 应用于密封特质将会给你一个 Coproduct - Alexey Romanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接