Scala 第二种方法

Scala 第二种方法,scala,Scala,我正在学习Scalacompose和以及方法的教程。有这样一个例子: scala> def addUmm(x: String) = x + " umm" scala> def addAhem(x: String) = x + " ahem" val ummThenAhem = addAhem(_).compose(addUmm(_)) 当我尝试使用它时,我得到一个错误: <console>:7: error: missing parameter type for ex

我正在学习Scala
compose
以及
方法的教程。有这样一个例子:

scala> def addUmm(x: String) = x + " umm"
scala> def addAhem(x: String) = x + " ahem"

val ummThenAhem = addAhem(_).compose(addUmm(_))
当我尝试使用它时,我得到一个错误:

<console>:7: error: missing parameter type for expanded function ((x$1) => addAhem(x$1).compose(((x$2) => addUmm(x$2))))
   val ummThenAhem = addAhem(_).compose(addUmm(_))
                             ^
<console>:7: error: missing parameter type for expanded function ((x$2) => addUmm(x$2))
   val ummThenAhem = addAhem(_).compose(addUmm(_))
                                               ^
<console>:7: error: type mismatch;
 found   : java.lang.String
 required: Int
     val ummThenAhem = addAhem(_).compose(addUmm(_))
甚至

val ummThenAhem = addAhem _ compose addUmm

教程中的代码有什么问题?后一个表达式是否与没有括号的第一个表达式相同?

来自
compose
文档:

在新的Function1中组成Function1的两个实例 最后应用的函数

所以你应该写

scala> val ummThenAhem = (addAhem _).compose(addUmm _)
ummThenAhem: String => java.lang.String = <function1>

addAhem
是一种方法<代码>合成
方法是在函数上定义的
addAhem
addAhem
从方法转换为函数,因此可以对其调用
compose
compose
需要一个函数作为其参数。通过将
addUmm
转换为一个带有
addUmm\uu
的函数,您为它提供了一个方法
addUmm
(下划线可以省略,因为编译器可以在知道需要函数时自动将方法转换为函数)。因此,您的代码:

addAhem _ compose addUmm

(addAhem _).compose(addUmm)
但不是

addAhem(_).compose(addUmm(_))
PS
我没有看你提供的链接。

我相信本教程是为Scala的早期版本(可能是2.7.7或更早版本)编写的。从那时起,编译器中发生了一些变化,即对类型系统的扩展,现在导致类型推断失败:

addUhum(_).compose(addAhem(_))
如果您只需编写以下代码,则函数的提升仍然可以使用该语法:

addUhum(_)
那么这个,

addUhum _
这是eta的扩展。它将方法转换为函数。另一方面,这:

addUhum(_)
是一个匿名函数。事实上,它是一个局部函数应用,因为这个参数没有被应用,整个过程都转换成一个函数。它扩展到:

x => addUhum(x)
精确的扩展规则有点难以解释,但基本上,函数将在最里面的表达式分隔符处“启动”。例外情况是部分函数应用程序,其中“x”被移到函数之外——如果使用
\uuu
代替参数

无论如何,它是这样扩展的:

val ummThenAhem = x => addAhem(x).compose(y => addUmm(y))

唉,类型推断器不知道x或y的类型。如果您愿意,您可以使用参数
-Ytyper debug

准确地看到它尝试了什么。为了完整起见,第二个示例如下所示:
val-ahemthenum=addAhem(u)。第二个(addUmm(u))
当它看起来应该是
val-ahemthenum1=(addAhem)。第二个(addUmm)
我不太确定用圆括号写的部分;编译器不会自动将方法转换为函数,至少对于Scala 2.10.2是这样。解决方法是将
addAhem
addUmm
声明为函数,以便
编写
,然后
在没有
\uu
的情况下工作。为什么不提供指向文档的链接?“you do it”不是答案
x => addUhum(x)
val ummThenAhem = x => addAhem(x).compose(y => addUmm(y))