Scala中方法,函数和部分应用函数的函数组合

时间:2011-10-07 05:26:13

标签: scala function-composition

与Stack Overflow问题 Compose and andThen methods 有点类似,我一直在通过Twitter的Scala School教程进行工作,很快就遇到了评论者所遇到的同样问题(这很棒) ,因为我上床认为我的问题已经解决了。)

在本教程中,它定义了两种方法:

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

虽然在较新版本的Scala中,您无法对其进行撰写:addUmm(_).compose(addAhem(_)),接受的答案(以及其他一些答案似乎取决于addUmm这一事实和addAhem是方法,而不是函数,这在尝试调用compose时会产生问题。我成功地运行了床,我满意地跑了:

scala> ((s: String) => s + " umm").compose((s: String) => s + " ahem")
res0: String => java.lang.String = <function1>

冷却。问题在于,虽然无法编写方法是有道理的,但是当我知道评估为Function1的值时我也是如此:

val a = (s: String) => s + " umm"
val b = (s: String) => s + " ahem"
val c = a(_).compose(b(_))

好吧,最后一行咳出与原问题相同的错误,即使这次是部分应用函数,而不是方法。原始问题中的一个答案(高排名,但不是接受的答案)似乎暗示它与部分应用程序如何扩展有关,解释是什么?

对于Scala新手,无论你是否明确指定a(_).compose(b(_))两个地方,推理器都会_: String出错,但a.compose(b)确实有点令人困惑。

2 个答案:

答案 0 :(得分:24)

a(_).compose(b(_))扩展为x => { a(x).compose(y => b(y) }。因此错误。你想要的是(x => a(x)).compose(y => b(y))。添加一对括号可以解决这个问题。

scala> (a(_)).compose(b(_: String))
res56: String => java.lang.String = <function1>

scala> res56("hello")
res57: java.lang.String = helloahemumm

但由于ab是函数,因此您可以避免所有这些问题,只需执行a compose b

答案 1 :(得分:4)

你可以简单地使用'a compose b'。

scala> val c = a compose b
c: String => java.lang.String = <function1>