加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

在Scala中推断相互依赖的默认方法实现

发布时间:2020-12-16 21:30:47 所属栏目:安全 来源:网络整理
导读:我想定义一个具有很好定义关系的属性的特征 – 例如,我们假设a * b = c.这个想法是,该特征的实现可以提供其中的两个,并具有自动导出的第三个属性的访问器. (这与Haskell的类型类相同,如果我正确地记得那些,那么如果你定义了 from Ord, =将被实现为!. - 尽管
我想定义一个具有很好定义关系的属性的特征 – 例如,我们假设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)
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读