Scala 中方法、函数和部分应用函数的函数组合
有点类似于 Stack Overflow 问题Compose 和 andThen 方法,我一直在研究 Twitter 的 Scala学校教程,很快就遇到了评论者遇到的同样问题(这很好,因为我上床睡觉时以为我的问题已经解决了)。
在本教程中,它定义了两个方法:
def addUmm(x: String) = x + " umm"
def addAhem(x: String) = x + " ahem"
在较新版本的 Scala 中,您无法像这样调用它们的 compose:addUmm(_).compose(addAhem(_))
,接受的答案(以及其他一些答案似乎取决于这样一个事实:addUmm 和 addAhem 是方法,而不是函数,这在尝试调用 compose 时会产生问题。我满意地去睡觉了,成功了run:
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(_))
好吧,最后一行会出现与原始问题确实如此,尽管这次它们是函数的部分应用,而不是方法。原始问题中的答案之一(排名很高,但不是公认的答案)似乎暗示它与如何有关。 解释是什么?
部分应用被扩展,对于a的 Scala 新手,事实上,无论您是否在两个地方显式指定 _: String
,推理器都会出错 a(_).compose(b(_))
,但是 < code>a.compose(b) 确实有点令人困惑。
Somewhat similar to Stack Overflow question Compose and andThen methods, I've been working through Twitter's Scala School tutorial and quickly ran into the same problem that a commenter had (which was great, because I went to bed thinking my problem was solved).
In the tutorial, it defines two methods as such:
def addUmm(x: String) = x + " umm"
def addAhem(x: String) = x + " ahem"
and while in newer versions of Scala, you can't call compose on them as such: addUmm(_).compose(addAhem(_))
, the accepted answer (and some of the other answers seem to hinge upon the fact that addUmm
and addAhem
are methods, not functions, which creates an issue when trying to call compose. I went to bed satisfied, having successfully run:
scala> ((s: String) => s + " umm").compose((s: String) => s + " ahem")
res0: String => java.lang.String = <function1>
Cool. The issue is that while not being able to compose methods makes some sense, when I the same thing with values I know evaluate to Function1
:
val a = (s: String) => s + " umm"
val b = (s: String) => s + " ahem"
val c = a(_).compose(b(_))
Well, that last line coughs up the same error that the original question did, even though they're partial applications of functions this time, not methods. One of the answers in the original question (highly-ranked, but not the accepted answer) seems to hint that it has to do with how the partial application is expanded, what is the explanation?
For a Scala newbie, the fact that the inferencer gets a(_).compose(b(_))
wrong no matter if you explicitly specify _: String
both places, but a.compose(b)
does is somewhat confusing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
a(_).compose(b(_))
扩展为x =>; { a(x).compose(y => b(y) }
。因此出现错误。您想要的是(x => a(x)).compose(y => b(y))
添加一对括号可以解决此问题,但由于
a
和b
是函数,因此您可以避免所有这些麻烦,只需执行 <代码>a组成b。a(_).compose(b(_))
expands tox => { a(x).compose(y => b(y) }
. Hence the error. What you want is(x => a(x)).compose(y => b(y))
. Adding a pair of parentheses fixes this.But since
a
andb
are functions, you can avoid all this cruft and simply doa compose b
.您可以简单地使用“a compose b”。
You can use simply 'a compose b'.