使用子类型扩展 scalaz 和隐式参数中的枚举
Extending Enum in scalaz and implicit parameters with subtypes
我在玩 scalaz,我想我可以扩展 Enum
类型 class 来让我自己更好地理解 scalaz。所以我写了这个:
sealed abstract trait Counter
case object First extends Counter
case object Second extends Counter
case object Third extends Counter
implicit val enumCounter: Enum[Counter] = new Enum[Counter] {
override def succ(a: Counter): Counter = a match {
case First => Second
case Second => Third
case Third => First
}
override def pred(a: Counter): Counter = a match {
case First => Third
case Second => First
case Third => Second
}
override def order(x: Counter, y: Counter): Ordering = {
val map = Map[Counter, Int](First -> 0, Second -> 1, Third -> 2)
implicitly[Order[Int]].order(map(x), map(y))
}
}
println(First |=> Third)
println(First.succ)
但事实证明它并没有像我希望的那样起作用。 First
没有 succ
也没有 |=>
,因为我创建了 Enum[Counter]
而不是 Enum[First]
。如果我写 First.asInstanceOf[Counter].succ
它开始解决。这对我来说很明显。但是我怎样才能以简单的方式实现 Enum
typeclass 呢?我不想为每个 Enum[First]
、Enum[Second]
...
声明单独的隐式值
我想到了两种可能的解决方案:
1) 使 Scala 将 Enum[First]
解析为 Enum[Counter]
。但我似乎无法理解这怎么可能,因为 Enum
只能是不变的
2) 也许scalaz 中有解决方案?
否则Enum
类型class开始相当有限,因为它不支持听起来很奇怪的Enum。
其实我也不确定这个问题属于多少scalaz
,大概要看解法是(1)还是(2)。如果解决方案是 (1) - 这个问题是纯粹的 scala。
我重新考虑了这个问题并改写了很多 - 并收到了答案,请看这个:
我在玩 scalaz,我想我可以扩展 Enum
类型 class 来让我自己更好地理解 scalaz。所以我写了这个:
sealed abstract trait Counter
case object First extends Counter
case object Second extends Counter
case object Third extends Counter
implicit val enumCounter: Enum[Counter] = new Enum[Counter] {
override def succ(a: Counter): Counter = a match {
case First => Second
case Second => Third
case Third => First
}
override def pred(a: Counter): Counter = a match {
case First => Third
case Second => First
case Third => Second
}
override def order(x: Counter, y: Counter): Ordering = {
val map = Map[Counter, Int](First -> 0, Second -> 1, Third -> 2)
implicitly[Order[Int]].order(map(x), map(y))
}
}
println(First |=> Third)
println(First.succ)
但事实证明它并没有像我希望的那样起作用。 First
没有 succ
也没有 |=>
,因为我创建了 Enum[Counter]
而不是 Enum[First]
。如果我写 First.asInstanceOf[Counter].succ
它开始解决。这对我来说很明显。但是我怎样才能以简单的方式实现 Enum
typeclass 呢?我不想为每个 Enum[First]
、Enum[Second]
...
我想到了两种可能的解决方案:
1) 使 Scala 将 Enum[First]
解析为 Enum[Counter]
。但我似乎无法理解这怎么可能,因为 Enum
只能是不变的
2) 也许scalaz 中有解决方案?
否则Enum
类型class开始相当有限,因为它不支持听起来很奇怪的Enum。
其实我也不确定这个问题属于多少scalaz
,大概要看解法是(1)还是(2)。如果解决方案是 (1) - 这个问题是纯粹的 scala。
我重新考虑了这个问题并改写了很多 - 并收到了答案,请看这个: