类型推断器如何在 reduceLeft 上工作? [英] How does the type inferencer work on reduceLeft?

查看:49
本文介绍了类型推断器如何在 reduceLeft 上工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

进一步​​我的另一个问题关于reduceLeftreduceLeftSeq上的签名是

Further to my other question about reduceLeft, the signature of reduceLeft on Seq is

def reduceLeft [B >: A] (f: (B, A) ⇒ B): B 

我们可以用诸如

List(1,2,3,4) reduceLeft (_ + _)

在这个例子中 AInt,所以 reduceLeft 需要一个 Function2[B >: Int, Int, B].不管reduceLeft 如何工作(无关紧要),类型推断器如何知道B 有一个+ 方法,当它可能是Any?

In this example A is Int, so reduceLeft expects a Function2[B >: Int, Int, B]. Regardless of how reduceLeft works (which is irrelevant), how does the type inferencer know that B has a + method, when it could be of type Any?

推荐答案

我认为 spec 有点解释了发生了什么.编译器将寻找最佳类型.当类型参数是逆变的时,选择的类型将是最大的(在本例中为 Any),否则(不变或协变)为最小(在本例中为 Int).

I think the section 6.26.4 Local Type Inference of the spec sort of explains what's going on. The compiler will look for an optimal type. When the type parameter is contravariant the type chosen will be maximal (in this case Any) and otherwise (invariant or covariant) minimal (in this case Int).

有几个例子我无法真正与reduceLeft联系起来.

There are a couple examples which I can't really relate to reduceLeft.

我注意到的是,在查看传递的匿名函数之前,推断似乎发生了:

What I did notice is the inference seems to happen before looking at the anonymous function passed:

scala> List(1,2).reduceLeft[Any](_.toString + _)
res26: Any = 12

但是如果我不帮助类型推断器:

But If I don't help the type inferencer:

scala> List(1,2).reduceLeft(_.toString + _)
<console>:8: error: type mismatch;
 found   : java.lang.String
 required: Int
              List(1,2).reduceLeft(_.toString + _)

编辑,我错了匿名函数被考虑在内,这是有效的:

Edit, I'm wrong the anonymous function is taken into account, this works:

List(1,2).reduceLeft((_:Any).toString + (_:Any).toString)

有一个编译器 -Ytyper-debug 选项可以运行:

There is a compiler -Ytyper-debug option that you can run on:

List(1,2).reduceLeft(_+_)

它会告诉你编译器以某种方式假设匿名函数的预期类型是 (Int, Int) =>Int,然后继续检查 _ + _ 并成功,然后将 B 推断为 Int.片段在这里:

It will show you that somehow the compiler assumes the expected type of the anonymous function is (Int, Int) => Int, then it proceeds to check the _ + _ against it and succeeds and then infers B as Int. Snippet here:

typed immutable.this.List.apply[Int](1, 2).reduceLeft: [B >: Int](f: (B, Int) => B)B
adapted immutable.this.List.apply[Int](1, 2).reduceLeft: [B >: Int](f: (B, Int) => B)B to ?, undetparams=type B
typing ((x$1, x$2) => x$1.$plus(x$2)): pt = (Int, Int) => Int: undetparams=, 
// some time later 
typed ((x$1: Int, x$2: Int) => x$1.+(x$2)): (Int, Int) => Int
adapted ((x$1: Int, x$2: Int) => x$1.+(x$2)): (Int, Int) => Int to (Int, Int) => Int, 
typed immutable.this.List.apply[Int](1, 2).reduceLeft[Int](((x$1: Int, x$2: Int) => x$1.+(x$2))): Int

我不知道为什么在没有类型归属的情况下,匿名函数被假定为 (Int, Int) =>;Int.

I don't know why in absence of type ascription the anonymous function is assumed to be (Int, Int) => Int.

这篇关于类型推断器如何在 reduceLeft 上工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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