我正在按照教程 Pattern matching & functional composition Scala compose
和 andThen
方法。有这样一个例子:
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 _
甚至
val ummThenAhem = addAhem _ compose addUmm
教程中的代码有什么问题?后一个表达式不是和第一个不带括号的表达式一样吗?
最佳答案
嗯,这个:
addUhum _
是eta展开。它将方法转换为函数。另一方面,这个:
addUhum(_)
是一个匿名函数。实际上,它是部分函数应用,因为没有应用此参数,而是将整个事物转换为函数。它扩展为:
x => addUhum(x)
扩展的确切规则有点难以解释,但是基本上,该函数将从最里面的表达式分隔符“开始”。部分函数应用程序是个异常(exception),如果使用 _
代替参数,则“x”会移到函数之外。
无论如何,这就是它的扩展方式:
val ummThenAhem = x => addAhem(x).compose(y => addUmm(y))
唉,类型推断器不知道 x 或 y 的类型。如果您愿意,您可以使用参数 -Ytyper-debug
确切地看到它尝试了什么。
关于scala - Compose 和 andThen 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7505304/