使用子类型扩展 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。

我重新考虑了这个问题并改写了很多 - 并收到了答案,请看这个: