Scala中的Typeclass实例继承

时间:2019-05-12 11:59:36

标签: scala typeclass

我正在翻译Scala中https://sebfisch.github.io/haskell-regexp/regexp-play.pdf中的Haskell代码以进行自学。 我以这种方式翻译了“类Semiring”(第2页):

  trait Semiring[S] {
    def zero: S
    def one: S
    def add(a: S, b: S): S
    def mult(a: S, b: S): S
  } 

以及与此相关的类SemiringI(第7页):

  trait SemiringI[S] extends Semiring[S] {
    def index: Int => S
  }

然后我必须提供特定类型参数的实例,因此我尝试以我认为是规范的方式进行操作,即将它们定义为隐式val。

  implicit val semiringLeftmost = new Semiring[LeftmostT] {
    // ...implementation of zero, one, add, mult...
  }

但是,当我必须为LeftmostT定义SemiringI实例时遇到一些问题:

  implicit val semiringILeftmost = new SemiringI[LeftmostT] {
    // ...implementation of zero, one, add, mult (same as for Semiring[LeftmostT])
    // ...implementation of index
  }

在我看来,我不得不重复在Semiring [LeftmostT]中已经定义的功能的实现,当然,这些功能是不可扩展的。 我在网上搜索了答案,但是找不到。 例如,在https://www.slideshare.net/jdegoes/scalaz-8-a-whole-new-game(幻灯片7)中,MonoididInt不会像我期望的那样重用Semigroup的append定义。

最后,我设法找到了一种进行方法,即:

  // traits Semiring[S] and SemiringI[S] defined as above

  class semiringLeftmostC extends Semiring[LeftmostT] {
        // ...implementation of zero, one, add, mult...
  }
  implicit val semiringLeftmost = new semiringLeftmostC()

  class semiringILeftmostC extends semiringLeftmostC with SemiringI[LeftmostT] {
        // ...implementation of index
  }

  implicit val semiringILeftmost = new semiringILeftmostC()

但是我不确定这是最好的。 有人可以告诉我是否还有其他可能性可以达到相同的目标,即在类型类实例的层次结构中重用代码?

谢谢。

0 个答案:

没有答案