Scala:避免在foldLeft中强制转换为类型参数

标签 scala casting fold

考虑这个片段定义了模拟状态的特征,用户期望在某种派生类型中实现该特征。在这一特征上,实用方法的集合应该能够提供具有实现类型的结果,类似于 Scala 库集合执行此操作的方式。为了实现这一点,我认为我需要使用实现类型参数化特征,如下所示:

trait State[+This <: State[This]] {
   def update : This  // result has type of State's implementor
}

现在我想定义一个多步更新方法,如下所示:

def update(steps: Int) : This 

当我尝试天真的方法时:

def update(steps: Int) : This = 
    (this /: (0 until steps))( (s,n) => s.update )

编译器提示类型不匹配:

 error: type mismatch;
 found: State[This]
 required: This

这是有道理的,因为在 State 中看到的 this 具有 State[This] 类型。 为了编译代码,我似乎必须进行显式转换:

def update(steps: Int) : This = 
    (this.asInstanceOf[This] /: (0 until steps))( (s,n) => s.update )

有没有办法避免这种显式转换,或者更一般地说,以更好的方式实现预期结果?谢谢。

最佳答案

您需要添加自类型注释以确保 StateThis:

trait State[+This <: State[This]] { this: This =>
  def update: This  // result has type of State's implementor
}

重新定义没有折叠的 update(Int) 方法的可能方法是:

def update(steps: Int): This = Iterator.iterate(this)(_.update).drop(steps).next

关于Scala:避免在foldLeft中强制转换为类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8383694/

相关文章:

Java语法歧义

python - 为什么 python 从字符串中返回数字?

java - 使用枚举/按位将 DaysOfWeek 作为单个整数存储在 sqlite 数据库中 - Java

list - 如何在 ocaml 中一次遍历两个列表?

scala - 如何欺骗 Scala 不为 Nothing 找到重复的隐式

scala - “unresolved dependency” 用于 SBT 上的 Spark 2.1.0

scala - 无法优化@tailrec注释的方法循环: it contains a recursive call not in tail position

ruby-on-rails - 关于 Rails 前端和 Scala 后端之间通信的建议

scala - 使用foldLeft 将列表转换为 map

haskell - 如何检查 BST 是否有效?