Scala 中自动派生的密封 trait/ADT 排序

Automatically derived sealed trait/ADT ordering in Scala

是否可以在 Scala 中自动导出密封特征族的顺序?

例如,如果能够做到:

sealed trait Letters
case object A extends Letters
case object B extends Letters

(A < B) == True

这感觉像是 Shapeless 可能能够处理的东西,但我看不到它当前是否存在。

我假设您希望排序反映定义的顺序,而不是按构造函数的名称排序。

这远没有您想象的那么有趣,因为 knownDirectSubclassesClassSymbol API returns a set of symbols, not an ordered sequence. I'm not an expert on scalac internals, but according to Eugene Burmako(谁是)上,knownDirectSubclasses 的签名只是反映了 scalac 中发生的事情。

我已经complaining about this for years, by the way, and at various points I've tried things like reading positions off the symbols,但它并没有真正起作用。

Shapeless 的通用机器必须在这里做出决定,因为它将密封特征表示为副产品,它们对元素进行排序。为了保持确定性,它使用构造函数的名称来对案例进行排序:

// Entering paste mode (ctrl-D to finish)

sealed trait Letters
case object B extends Letters
case object A extends Letters

// Exiting paste mode, now interpreting.

defined trait Letters
defined object B
defined object A

scala> shapeless.Generic[Letters]
res5: shapeless.Generic[Letters]{type Repr = shapeless.:+:[A.type,shapeless.:+:[B.type,shapeless.CNil]]} = anon$macro@71a11be4

如果这就是您想要的,那么您就大功告成了 - 只需在 Shapeless 支持的泛型推导上找到 good tutorial 并制定详细信息即可。不幸的是,在大多数情况下,它可能不是您想要的,尽管 (EastNorthSouthWest?BlueGreenRed?),而你想要的(定义排序)似乎不太可能。

Enumeratum时,我得出了和特拉维斯一样的结论,即knownDirectSubclasses无法提供有关声明顺序的信息。

尽管如此,在给定模块的主体内,AST 仍然是有序的(类型为 List[Tree]),所以这就是我设法制作 declaration-based ordering work 并提供 indexOf 方法。一旦你有了密封特征实例的有序序列,得到一个 Order 就很简单了。

抱歉,这不是无形的答案..