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

Scala:不可变性和路径依赖类型兼容性

发布时间:2020-12-16 18:22:16 所属栏目:安全 来源:网络整理
导读:我已经围绕这个主题提出了一些问题,但这次我想进行更一般的讨论,因为在我看来,Scala缺少一些非常重要的块. 考虑以下代码(从我的实际项目中简化), trait World { type State : StateIntf def evolve(s: State): State def initialState: State}class Algorith
我已经围绕这个主题提出了一些问题,但这次我想进行更一般的讨论,因为在我看来,Scala缺少一些非常重要的块.

考虑以下代码(从我的实际项目中简化),

trait World {
  type State <: StateIntf
  def evolve(s: State): State
  def initialState: State
}

class Algorithm(world: World) {
  def process(s: world.State) {
    val s1 = world.evolve(s)
    // ... do something with s and s1
  }
}

一切看起来都很美丽和数学,但是

object SomeWorld extends World {...}
new Algorithm(SomeWorld).process(SomeWorld.initialState)  // incompatible type

当然你可以用以下方式做

trait World {
  type State <: StateIntf
  var s: State
  def evolve: Unit      // s = next state
  def initialize: Unit  // s = initial state
  def getState: StateIntf = s
}

但我们只是回到可变世界.

我被告知这是因为Scala没有流量分析.如果这是问题,Scala不应该得到那块吗?我只需要compilor可以知道从val传递给val的值是相同的,因此它们的内部类型必须一致.这对我来说似乎很自然,如:

> val是最基本的概念,涉及scala中的不变性
>需要路径依赖类型兼容性来模拟具有完全不变性的世界(从数学角度非常需要)
>通过vals的流量分析解决了这个问题

我要求太多了吗?或者已经有一种很好的方法来解决它?

解决方法

在使用路径依赖类型时,编译器有时需要一些帮助来证明您正在做的事情是合法的.即,正如您所说,编译器缺少流分析,因此我们必须明确告诉它我们不仅仅使用任何World,我们正在使用SomeWorld,以便我们可以使用SomeWorld.initialState.

在您的情况下,如果您更改算法,如下所示:

class Algorithm[W <: World](world: W) {
  def process(s: world.State) {
    val s1 = world.evolve(s)
    // ... do something with s and s1
  }
}

然后以下编译:

object SomeWorld extends World {...}
new Algorithm[SomeWorld.type](SomeWorld).process(SomeWorld.initialState)

(编辑:李大同)

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

    推荐文章
      热点阅读