在Scala中推断相互依赖的默认方法实现
我想定义一个具有很好定义关系的属性的特征 – 例如,我们假设a * b = c.这个想法是,该特征的实现可以提供其中的两个,并具有自动导出的第三个属性的访问器.
(这与Haskell的类型类相同,如果我正确地记得那些,那么如果你定义了< from Ord,> =将被实现为!.< - 尽管你可以定义任何功能子集,只要剩下的可以推断出来)(我不记得Haskell类的类正确了.) 天真的做法实际上工作得很好: trait Foo { // a * b = c def a: Double = c / b def b: Double = c / a def c: Double = a * b } class FooOne(override val a: Double,override val b: Double) extends Foo class FooTwo(override val a: Double,override val c: Double) extends Foo 在这里,FooOne和FooTwo的实现是Foo的完整实现,并且按预期的方式表现.到现在为止还挺好;这种方法允许类定义两个属性,并获得第三个“免费”. 但是,如果定义了第三类,事情开始看起来不太乐观: class FooFail(override val a: Double) extends Foo 这个编译很好 – 但是,如果它的b或c方法被评估,它将导致堆栈溢出. 所以天真的方法给出了Haskell类型类方法的推理方面,但是我们没有编译时的安全性.我想要的是编译器抱怨如果不到两个方法是通过实现类来定义的.显然现在的语法在这里是不够的我们需要将这些方法视为抽象的,尽管有一个默认的实现,当且仅当依赖方法是非抽象的时才可以使用. Scala是否公开适当的语义来定义这一点? (我没有问题,如果有一个有点迂回的方式来定义它,类似于union types,因为我不知道在这个语言的任何一流的支持). 如果没有,我会采取天真的做法,只需定期和测试我的课程.但是我真的认为这是类型系统应该能够捕获的东西(毕竟不是Ruby):). 解决方法
使用含义:
object test { case class A(v : Double) case class B(v : Double) case class C(v : Double) implicit def a(implicit b : B,c : C) = A(c.v / b.v) implicit def b(implicit a : A,c : C) = B(c.v / a.v) implicit def c(implicit a : A,b : B) = C(a.v * b.v) def foo(implicit a : A,b : B,c : C) = a + "," + b + "," + c // Remove either of these and it won't compile implicit val aa = A(3) implicit val bb = B(4) def main(args : Array[String]) { println(foo) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |