我正在将https://sebfisch.github.io/haskell-regexp/regexp-play.pdf中的Haskell代码翻译成Scala,以便自己学习。我用这样的方式翻译了"class 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
}然后,我必须为特定类型的参数提供实例,所以我尝试以我认为是规范的方式进行操作,即将它们定义为隐式vals。
implicit val semiringLeftmost = new Semiring[LeftmostT] {
// ...implementation of zero, one, add, mult...
}然而,当我必须为SemiringI定义一个LeftmostT实例时,我遇到了一些问题:
implicit val semiringILeftmost = new SemiringI[LeftmostT] {
// ...implementation of zero, one, add, mult (same as for Semiring[LeftmostT])
// ...implementation of index
}在我看来,我不得不重复在SemiringLeftmostT中已经定义的函数的实现,当然,这是不能扩展的。我在网上寻找答案,但找不到答案。例如,在https://www.slideshare.net/jdegoes/scalaz-8-a-whole-new-game (幻灯片7)中,MonoidInt并没有像我预期的那样重用来自半群的追加的定义。
最后,我设法找到了一种方法,即:
// 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()但我不确定这是最好的。请有人向我解释一下,是否还有其他可能达到同样的目标,即在类型化实例的层次结构中重用代码?
提前谢谢。
发布于 2022-06-22 17:18:11
多亏了这个职位和Scala 3的出现,我编写了类层次结构的简明版本:
trait Semiring[S] {
def zero: S
def one: S
def add(a: S, b: S): S
def mult(a: S, b: S): S
}
trait SemiringI[S] extends Semiring[S] {
def index(i: Int): S
}
given semiringLeftmost: Semiring[LeftmostT] with {
// implementation of Semiring functions
}
given semiringILeftmost: SemiringI[LeftmostT] with {
export semiringLeftmost.*
override def index(i: Int): LeftmostT = ??? // actual implementation not relevant
}但是,我可以从上面提到的文章中推断,对于如何在Scala 3中编码类型类型层次结构,似乎还没有达成共识。我发现的正式文档示例似乎重新定义了派生特征(https://dotty.epfl.ch/docs/reference/contextual/type-classes.html)中的函数。
https://stackoverflow.com/questions/56099022
复制相似问题