【问题标题】:Automatically derived sealed trait/ADT ordering in ScalaScala 中自动派生的密封特征/ADT 排序
【发布时间】:2016-07-18 05:13:31
【问题描述】:

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

例如,如果能够这样做就好了:

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

(A < B) == True

这感觉像是 Shapeless 可以处理的东西,但我看不出它目前是否存在。

【问题讨论】:

    标签: scala generic-programming shapeless


    【解决方案1】:

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

    这远没有您想象的那么有趣,因为ClassSymbol API 上的knownDirectSubclasses 返回一组符号,而不是有序序列。我不是 scalac 内部的专家,但according to Eugene Burmako(谁是),knownDirectSubclasses 的签名只是反映了 scalac 中发生的事情。

    顺便说一句,我已经complaining about this 很多年了,在很多时候我都尝试过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$45$1@71a11be4
    

    如果这是你想要的,那么你就准备好了——只需在 Shapeless 驱动的泛型推导上找到 good tutorial 并计算出详细信息。不幸的是,在大多数情况下,它可能不是您想要的(EastNorthSouthWest?BlueGreenRed?),以及您想要的(定义排序) ) 似乎不太可能。

    【讨论】:

    • 问题中的示例可能只是说明性的,但从表面上看,字母顺序(这是 shapeless 提供的)正是这里所要求的 ;-)
    • @MilesSabin 够公平的!不过,这几乎是我能想到的唯一示例,其中字母构造函数名称是您想要的。 :)
    【解决方案2】:

    在写Enumeratum 时,我得出了与Travis 相同的结论,即knownDirectSubclasses 无法提供有关申报顺序的信息。

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

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

    【讨论】:

      猜你喜欢
      • 2015-05-26
      • 1970-01-01
      • 2017-09-08
      • 1970-01-01
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 2020-04-27
      • 2018-12-18
      相关资源
      最近更新 更多