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

Mar*_*ger 17 scala function-composition

有点类似Stack Overflow问题Compose和andThen方法,我一直在通过Twitter的Scala学校教程,很快就遇到了一个评论者所遇到的同样的问题(这很棒,因为我上床认为我的问题已经解决了).

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

def addUmm(x: String) = x + " umm"
def addAhem(x: String) = x + " ahem"
Run Code Online (Sandbox Code Playgroud)

同时Scala中的较新版本,你不能要求他们撰写这样:addUmm(_).compose(addAhem(_)),公认的答案(以及一些其他的答案似乎基于这样的事实,以铰链addUmmaddAhem一些方法,而不是功能,当试图创建一个问题打电话给我.我上床睡觉满意,成功跑了:

scala> ((s: String) => s + " umm").compose((s: String) => s + " ahem")
res0: String => java.lang.String = <function1>
Run Code Online (Sandbox Code Playgroud)

凉.问题在于,虽然无法编写方法是有道理的,但当我知道评估的价值相同的时候Function1:

val a = (s: String) => s + " umm"
val b = (s: String) => s + " ahem"
val c = a(_).compose(b(_))
Run Code Online (Sandbox Code Playgroud)

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

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

mis*_*tor 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
Run Code Online (Sandbox Code Playgroud)

但既然ab是功能,你可以避免所有这些残酷而且干脆做a compose b.

  • @Marc:想象一下你有这行代码:`xs filter {f} map {g}`.假设在后一个时间点你需要在末尾添加一个`toList`.你这么说:`xs filter {f} map {g} toList`.这可能会导致分号推断问题.要避免这些问题,您可以在结尾处添加分号,也可以使用换行符.这两个选项都是丑陋的IMO.为了避免所有这些废话,我总是喜欢使用`xs.filter(f).map(g)`.使用这种语法重构总是更容易. (2认同)