我有一个由某种“状态机”(“流程图”)定义的分布式系统
每个系统将其状态写入共享“日志”中
我将每个状态表示为密封特性的一部分以及该状态的给定“状态”
我想“合并/减少”到一个单一的状态,代表当前的进展。
(有一些放松的地方,因为不是所有的必须成功,以便最终状态成功完成)
有2个密封的特征代表流:
sealed trait System
case object A extends System
case object B extends System
case object C extends System
...
sealed trait Status
case object Pending extends Status
case object InProgress extends Status
case object Success extends Status
case object Fail extends Status
日志:
A, Success
B, Fail
C, Pending
...
...
现在有一组规则,我使用它们来定义单个状态降低
基本上它会优先考虑A < B < C, ... < Z
和/或Pending < InProgress < Success < Fail
因此,如果存在以下状态:(A, Success)
与(C, Pending)
我想把它简化为(C,Pending)
如果(A,Success)
与(B, Fail)
我想把它缩小到(B, Fail)
在我的例子中,我可以将其建模为一个简单的整数比较(可能带有一个我显式测试的异常值)
我不清楚如何使密封的特征可比较/可排序,这将使我的生活方式更容易
沿着这些思路做就足够了:
def reduce(states: Seq[(System,Status)]) : (System,Status) = {
states.order... {left.system < right.system) && (a.status < b.status) ... possibly another ordering test ....}.tail // take the last one in the ordering
}
4条答案
按热度按时间rnmwe5a21#
您可以定义
scala.math.Ordering[Status]
:在
reduce
中,您可以您的
Status
对象将被<
和朋友丰富。也可以让你的
trait
扩展Ordered[Status]
,它在trait中定义了一个规范的顺序:这样就不必导入
mkOrderingOps
,但我个人不喜欢在compare
方法中向前使用扩展case objects
(在每种情况下使用样板compare
对象的替代方案更糟糕)。mzaanser2#
一种方法是在几个
Map
中定义System
和Status
的优先级,然后通过Ordering.by
定义(System, Status)
的顺序:请注意,在上面的示例代码中,不匹配的
System/Status
的默认值被设置为0
(表示最低优先级)。可以根据需要将它们设置为任何其他值。要减少
(System, Status)
s中的Seq
:cwtwac6a3#
考虑使用enumatum-cats
CatsOrderValueEnum
方法定义顺序其输出
在哪里
sqserrrh4#
一旦你给每个
case object
分配了一个整数,你就可以通过减去它们来编写你自己的Ordering#compare
方法:然后,您可以轻松地对序列进行排序: