未推断出多参数闭包参数类型 [英] Multiple parameter closure argument type not inferred

查看:22
本文介绍了未推断出多参数闭包参数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a piece of code that I can't get to behave in the way I'd like. I have a class defined in the following way (stripped down for this):

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)))
  }
}

在玩这门课时,我尝试了一些我认为微不足道的事情:

When playing around with this class I tried to something that I thought would be trivial:

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

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

For the last line I receive the following error:

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

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

I can of course specify the closure parameter types and it works correctly but why doesn't type inference work here? Of course I could also specify the generic types for the function (see below for both solutions).

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

I thought Scala carried out a 'scan' to infer types and would see beh2 and passed into the function and assume U here to be Int. Is there some way I can fix this without specify the types of the input parameters (for the closure or the generics)?

我拥有的两个修复示例:

Examples of the two fixes I have:

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

推荐答案

这个scala-debate thread 讨论这里发生的事情.问题是 Scala 的类型推断是按参数列表发生的,而不是按参数发生的.

See this scala-debate thread for a discussion of what's going on here. The problem is that Scala's type inference happens per parameter list, not per parameter.

正如 Josh Suereth 在该线程中指出的那样,当前的方法有充分的理由.如果 Scala 有每个参数的类型推断,编译器就无法推断同一参数列表中的类型的上限.考虑以下几点:

As Josh Suereth notes in that thread, there's a good reason for the current approach. If Scala had per-parameter type inference, the compiler couldn't infer an upper bound across types in the same parameter list. Consider the following:

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 的类型.

f(y, z) works exactly as we'd expect, but g(y)(z) gives a type mismatch, since by the time the compiler gets to the second argument list it's already chosen Y as the type for A.

这篇关于未推断出多参数闭包参数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆