Jea*_*let 7 scala type-inference anonymous-function
什么时候Scala编译器真的需要匿名函数参数的类型信息?
例如,给定此功能:
def callOn[T,R](target: T, f: (T => R)) = f(target)
Run Code Online (Sandbox Code Playgroud)
然后我不能这样使用它:
callOn(4, _.toString)
=> error: missing parameter type for expanded function ((x$1) => x$1.toString)
Run Code Online (Sandbox Code Playgroud)
我必须指明
callOn(4, (_: Int).toString)
Run Code Online (Sandbox Code Playgroud)
这是相当丑陋的.为什么我的示例不起作用,而集合类上的map,filter,foldLeft等方法似乎不需要这种显式类型?
Kev*_*ght 14
类型推断的技巧是将其视为迭代细化的过程.每个参数块可用于推断一些类型参数,然后可以在后续块中使用.所以采取以下定义:
def chain[T,A,B](x: T)(fn1: T=>A)(fn2: A=>B) = fn2(fn1(x))
Run Code Online (Sandbox Code Playgroud)
称为:
chain(2)(_*10)("xxx"+_)
Run Code Online (Sandbox Code Playgroud)
那么这是怎么推断出来的呢?首先,我们从(2)已知具有该类型的块开始Int.将其替换回T我们得到的参数:
def chain[A,B](x: Int)(fn1: Int=>A)(fn2: A=>B) = fn2(fn1(x))
Run Code Online (Sandbox Code Playgroud)
下一个参数块(_*10),我们现在知道的占位符的类型_是Int......再乘以一个Int由Int给出了另一个Int.即使发生溢出,返回类型也是如此; 在极端,它可能抛出一个异常,但异常的类型Nothing是类型系统中其他所有东西的子类,所以我们仍然可以说Nothingis-an Int和推断类型Int仍然有效.
通过A推断,该方法变为:
def chain[B](x: Int)(fn1: Int=>Int)(fn2: Int=>B) = fn2(fn1(x))
Run Code Online (Sandbox Code Playgroud)
只留下B哪些可以推断出来("xxx"+_).由于String + Int是String,该方法现在是:
def chain(x: Int)(fn1: Int=>Int)(fn2: Int=>String) = fn2(fn1(x))
Run Code Online (Sandbox Code Playgroud)
由于方法的返回类型来自直接fn2,也可以明确显示完整性:
def chain(x: Int)(fn1: Int=>Int)(fn2: Int=>String): String = fn2(fn1(x))
Run Code Online (Sandbox Code Playgroud)
你有它,所有类型都安全地解决了,并且该方法被证明是静态有效的.
在您的情况下,您需要在T可以R从类型推断之前推断类型T=>R.为此,您必须将参数拆分为两个不同的块,以咖喱形式编写方法:
def callOn[T,R](target: T)(f: (T => R)) = f(target)
Run Code Online (Sandbox Code Playgroud)
这个问题在这里也有答案:
您期望,......对于Scala的编译器,要将两个参数都考虑到两次,以推断出正确的类型.但是,Scala并没有这样做 - 它只使用从一个参数列表到下一个参数列表的信息,而不是从一个参数到下一个参数.这意味着独立地分析参数f和a [WS:在这种情况下的目标和f],而没有知道另一个是什么的优点.
请注意,它确实有咖喱版本的工作:
scala> def callOn[T,R](target: T)(f: (T => R)) = f(target)
callOn: [T,R](target: T)(f: (T) => R)R
scala> callOn(4)(_.toString)
res0: java.lang.String = 4
scala>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3337 次 |
| 最近记录: |