Scala函数组合:括号和类型

时间:2016-09-16 17:13:18

标签: scala syntax

(1)在Scala REPL中定义了两个函数:

scala> def f(s: String) = "f(" + s + ")"
f: (s: String)String

scala> def g(s: String) = "g(" + s + ")"
g: (s: String)String

(2)在没有括号的情况下编写它们可以按预期工作:

scala> f _ compose g _
res18: String => String = <function1>

(3)用括号括起来不会:

scala> f(_).compose(g(_))
<console>:14: error: missing parameter type for expanded function ((x$1) => f(x$1).compose(((x$2) => g(x$2))))
       f(_).compose(g(_))
         ^
<console>:14: error: missing parameter type for expanded function ((x$2) => g(x$2))
       f(_).compose(g(_))
                      ^
<console>:14: error: type mismatch;
 found   : String
 required: Int
       f(_).compose(g(_))
                     ^

问题1: 有人可以解释原因吗?

问题2: 为什么类型不匹配?为什么Scala期待Int

(4)通过使前两个错误消失,带括号的f(_)周围似乎有所帮助:

scala> (f(_)).compose(g(_))
<console>:14: error: missing parameter type for expanded function ((x$2) => g(x$2))
       (f(_)).compose(g(_))
                    ^

问题3: 为什么这些括号有帮助?

问题4: 为什么Scala需要参数类型,即使它们分别在fg中明确定义?

(5)最后,添加参数类型使其起作用:

scala> (f(_)).compose(g(_:String))
res22: String => String = <function1>

您能解释一下发生了什么,并提供替代语法来实现合成吗?

感谢。

1 个答案:

答案 0 :(得分:2)

您可以使用魔术评论看到(意外)扩展:

'com.firebase:firebase-client-android:2.3.1'

如您所示,函数文字需要约束约束。 scala> f(_).compose(g(_)) // show [snip] val res0 = ((x$1) => f(x$1).compose(((x$2) => g(x$2)))) 是eta扩展,与f _不同,后者是f(_)的糖。

由于非预期的应用程序x => f(x)返回一个字符串,这是一个用于索引的f(x$1),因此您将获得添加的类型不匹配。

下划线涉及许多SO问题,包括一个规范。