Scala函数签名:(p:(T,B)⇒布尔值)是什么意思?

时间:2015-02-22 22:53:49

标签: scala

在阅读Scala文档时,我对一些函数签名感到困惑:

def corresponds[B](that: GenSeq[B])(p: (T, B) ⇒ Boolean): Boolean 

那么,究竟是什么意思呢?

(p: (T, B) ⇒ Boolean)

3 个答案:

答案 0 :(得分:3)

这意味着p是一个函数,它接受TB类型的两个参数并返回Boolean

答案 1 :(得分:2)

(that: GenSeq[B])中,that是参数的名称,GenSeq[B]是其类型。

(p: (T, B) ⇒ Boolean)中,p是参数的名称,(T, B) ⇒ Boolean)是其类型。

答案 2 :(得分:0)

这里有两件事情,这可能让你感到困惑。我将在下面分析这个声明:

def corresponds
  [B] // Type parameter
  (that: GenSeq[B]) // FIRST parameter list
  (p: (T, B) ⇒ Boolean) // SECOND parameter list
  : Boolean // return type

因此,可能会让您失望的第一件事是Scala接受多个参数列表。这样做有很多好处:

  • 您可以使用句法糖,例如:(1 to 10).foldLeft(0) { case (a, b) => a + b };
  • 以前参数列表的类型可以指导对后续参数列表的推断 - 这也发生在前面的示例中;
  • 最后一个参数列表可以是“隐式”。

在下面的函数中,前两个原因很可能是使用两个参数列表的原因。假设你有类似的东西:

correponds(Gen.alphaStr)(_ != _)

类型B将被推断为String,因此后面的函数中的类型都将是已知的。不,如果它只是一个参数列表,就像这样:

corresponds(Gen.alphaStr, _ != _)

然后不会推断类型B,因为它还取决于函数的类型。例如,这里:

corresponds(Gen.alphaStr, (a: T, b: Any) => a != b)

B的类型为Any而不是String。现在,因为它无法在第一种情况下推断出类型,所以编译将失败。拆分两个参数列表会强制编译仅依赖于推理的第一个参数,这消除了歧义。

然后,还有语法糖,例如:

corresponds(Gen.alphaStr) {
  case (x, "positive") => x > 0
  case (x, "negative") => x < 0
  case _ => x == 0
}

与此之间差别不大:

corresponds(Gen.alphaStr, {
  case (x, "positive") => x > 0
  case (x, "negative") => x < 0
  case _ => x == 0
})

但是可读性是由像这样的小事做成的。

现在,第二个因素是函数类型的语法。 b: (T, B) => Boolean表示名为b的参数的类型为(T, B) => Boolean,这意味着一个函数采用两个参数,第一个类型为T,第二个类型为B,并返回Boolean类型的值。

请参阅上面的各种示例,了解作为参数传递的函数。