【问题标题】:Scala function composition: brackets and typesScala函数组合:括号和类型
【发布时间】:2016-09-16 17:13:17
【问题描述】:

(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>

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

谢谢。

【问题讨论】:

    标签: scala syntax


    【解决方案1】:

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

    scala> f(_).compose(g(_)) // show
    [snip]
          val res0 = ((x$1) => f(x$1).compose(((x$2) => g(x$2))))
    

    正如您所展示的,函数文字需要限制参数。 f _ 是 eta 扩展,与 f(_) 不同,x =&gt; f(x) 是糖。

    由于意外的应用程序f(x$1) 返回一个字符串,这是一个用于索引的Int =&gt; Char,因此您会得到添加的类型不匹配。

    下划线包含在许多 SO 问题中,包括一个规范问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      相关资源
      最近更新 更多