在Scala中自动导出密封特征/ ADT排序

时间:2016-03-30 09:30:32

标签: scala generic-programming shapeless

是否可以在Scala中自动派生密封特征族的订单?

例如,能够这样做很好:

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

(A < B) == True

感觉就像Shapeless可以处理的东西,但我无法看到它是否存在。

2 个答案:

答案 0 :(得分:5)

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

由于ClassSymbol API上的knownDirectSubclasses会返回一组符号,而不是有序序列,因此这并不像您预期​​的那样有趣。我不是scalac内部的专家,但是according to Eugene Burmako(谁),knownDirectSubclasses的签名只反映了scalac中发生的事情。

顺便说一句,我已经complaining about this多年了,在不同的时间点我尝试了reading positions off the symbols之类的东西,但它并没有真正起作用。

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

// 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$45$1@71a11be4

如果这是您想要的,那么您已经完成了设置 - 只需在Shapeless驱动的泛型推导上找到good tutorial并计算出详细信息。不幸的是,在大多数情况下,它可能不是您想要的(EastNorthSouthWestBlueGreen,{ {1}}?),你想要什么(定义排序)似乎不太合理。

答案 1 :(得分:0)

在撰写Enumeratum时,我得出与Travis相同的结论,knownDirectSubclasses无法提供有关声明顺序的信息。

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

对不起,这不是一个无形的答案..