【问题标题】:Scala: immutability and path-dependent type compatibilityScala:不变性和依赖路径的类型兼容性
【发布时间】:2013-01-27 03:58:29
【问题描述】:

我已经围绕这个主题提出了一些问题,但这次我想对其进行更一般的讨论,因为在我看来 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 不应该得到那部分吗?我只需要编译器可以知道从val 传递到val 的值是相同的,因此它们的内部类型必须一致。这对我来说似乎很自然,因为:

  1. val 是涉及 scala 中不变性的最基本概念
  2. 需要依赖路径的类型兼容性才能对 World 等具有完全不变性的事物进行建模(从数学角度来看这是非常需要的)
  3. 通过vals的流分析解决问题

我要求太多了吗?还是已经有很好的解决方法了?

【问题讨论】:

    标签: scala path-dependent-type


    【解决方案1】:

    我认为泛型为这个问题提供了一个更简单的解决方案:

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

    【讨论】:

    • 我认为像 [S <: stateinf>
    • @Odomontois 谢谢。我忘记了界限。
    • 经过 2 年多...终于意识到为什么泛型对我不起作用(但在大多数情况下,我会说您的解决方案很棒)。在我的情况下,我有两个具有相同状态类型的世界,我想将世界 1 的功能应用于世界 2 中生成的状态,但该状态在使用前必须通过转换器。这种行为最好由内部类型建模,因为泛型将允许在不转换的情况下应用函数,这在编译和运行时很危险,但会产生废话。我不得不说我几乎多次犯了这个错误,并且每次在编译时都被警告。
    【解决方案2】:

    编译器有时需要一点帮助来证明您在使用路径相关类型时所做的事情是合法的。也就是说,正如你所说,编译器缺少流分析,所以我们必须明确告诉它我们不只是使用任何World,我们正在使用SomeWorld,以便我们可以使用SomeWorld.initialState

    在您的情况下,如果您像这样更改Algorithm

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-17
      • 2013-06-20
      • 2011-03-20
      • 1970-01-01
      • 2019-08-24
      • 2022-12-21
      • 1970-01-01
      • 2016-11-23
      相关资源
      最近更新 更多