scala - 未推断多参数闭包参数类型

标签 scala compiler-construction types programming-languages type-inference

我有一段代码无法按照我想要的方式运行。我有一个按以下方式定义的类(为此进行了精简):

class Behaviour[T](private val rule: Time => T) {
  def map1[U, V](behaviour: Behaviour[U], func: (T, U) => V): Behaviour[V] = {
    new Behaviour(time => func(this.at(time), behaviour.at(time)))
  }
}

在玩这个类(class)时,我尝试了一些我认为微不足道的事情:

val beh = Behaviour(time => 5)
val beh2 = Behaviour(time => 5)
beh.map1(beh2, (a, b) => a + b)

对于最后一行,我收到以下错误:

<console>:13: error: missing parameter type
          beh.map1(beh2, (a, b) => a + b)
                             ^

我当然可以指定闭包参数类型并且它可以正常工作,但是为什么类型推断在这里不起作用?当然,我也可以指定函数的泛型类型(两种解决方案见下文)。

我认为 Scala 执行了“扫描”来推断类型,并且会看到 beh2 并传递到函数中,并假设这里的 UInt.有什么方法可以解决这个问题而不指定输入参数的类型(对于闭包或泛型)?

编辑:我的两个修复示例:

beh.map1[Int, Int](beh2, (a, b) => a + b)
beh.map1(beh2, (a, b : Int) => a + b)

最佳答案

参见this scala-debate thread讨论这里发生的事情。问题是 Scala 的类型推断是针对每个参数列表进行的,而不是针对每个参数进行的。

正如 Josh Suereth 在该帖子中指出的那样,当前的方法有一个很好的理由。如果 Scala 具有按参数类型推断,则编译器无法推断同一参数列表中类型的上限。考虑以下因素:

trait X
class Y extends X
class Z extends X

val y = new Y
val z = new Z

def f[A](a: A, b: A): (A, A) = (a, b)
def g[A](a: A)(b: A): (A, A) = (a, b)

f(y, z) 的工作方式与我们期望的完全一样,但是 g(y)(z) 给出了类型不匹配,因为到编译器时到达第二个参数列表时,它已选择 Y 作为 A 的类型。

关于scala - 未推断多参数闭包参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9118264/

相关文章:

compiler-construction - 请参阅以前的 ./configure 选项

compiler-construction - 使用 Antlr 创建语言

sql - PostgreSQL ORDER BY 问题 - 自然排序

arrays - 处理多种类型和数组时如何编写 "good"Julia代码(多重分派(dispatch))

scala - Spark HBase连接超时/挂起

scala - 在 Spark 中连接 Maptype 值时如何处理空值

scala - 在Spark的RDD中更新值(value)的有效方法是什么?

scala - 如何连接两个表并将结果映射到 slick 中的案例类

c# - 如何根据 C# 中缺少的属性生成编译器错误?

c# - 如何在 .NET 中在运行时定义属性的类型?