功能集中的特征功能

时间:2018-03-06 04:40:12

标签: scala

这是关于Scala函数中的句法糖的问题,可以找到类似的讨论herehere。这两个答案都给出了很好的见解,但我仍然无法理解我的头脑。

也就是说,我无法理解功能如何运作

特色功能(见下面的代码):

  • S(ELEM)
  • 集(ELEM)

让我们看一个例子,

object devScript extends App {
  type Set = Int => Boolean
  def contains(s: Set, elem: Int): Boolean = s(elem)

  def singletonSet1(elem: Int): Set = (x: Int) => x == elem
  def singletonSet2(elem: Int): Set = Set(elem)

  println(contains(singletonSet1(5), 5))
  println(contains(singletonSet2(5), 5))
}

返回:

true
true

singletonSet1singletonSet2给出了相同的结果,那么它们只是两个表达相同但不同形式的函数吗?而且,在没有明确定义布尔子句的情况下,函数如何返回true / false

2 个答案:

答案 0 :(得分:2)

我认为这个例子有点令人困惑,因为范围内有Set的两个定义。您可以定义自己的类型别名Set,其类型为Int并返回BooleanInt => Boolean的函数。另一方面,您在范围内的Scala集合中也有Set,其apply函数的类型也相同:Int => Boolean。我们来看看REPL中的这些类型:

scala> singletonSet1 _
res1: Int => Set = $$Lambda$1261/1618596377@4ed90b04

scala> singletonSet2 _
res2: Int => Set = $$Lambda$1262/224661478@14f08a97

scala> Set(1).apply _
res3: Int => Boolean = $$Lambda$1352/273821181@17d6b6e

// same as apply above
scala> Set(1)(_)
res4: Int => Boolean = $$Lambda$1377/1981148063@4ebe0e3f

scala> singletonSet1(1)
res5: Set = $$Lambda$1230/593573468@7574d30b

scala> singletonSet1(1)(1)
res6: Boolean = true

// or similarly:
scala> singletonSet2(1)(1)
res7: Boolean = true

正如您所看到的apply,也写为()符合您需要从singletonSet[1|2]函数返回的类型。

你是对的,它们都可以用作以不同形式实现的函数:使用singletonSet1的闭包和在Set情况下使用常规Scala singletonSet2

请注意singletonSet[1|2]不会返回布尔值,如果您给它Boolean,它会返回一个返回Int的函数。还有一个层次的间接涉及。如果您完全写出这些函数的类型,它将如下所示:Int => Int => Boolean或等效:Int => Set

巧合的是,我写了一篇博文,试图解释这是如何运作的。你可以在这里查看:http://izmailoff.github.io/programming%20languages/functional%20programming/functional_sets。希望它足够清楚。

答案 1 :(得分:2)

Set(elem)引用scala.collection.Set的伴随对象,它是,因此不会被type定义{{1 }}

只需运行它即可查看:

Set

它会打印object devScript extends App { type Set = Int => Boolean def contains(s: Set, elem: Int): Boolean = s(elem) def singletonSet1(elem: Int): Set = (x: Int) => x == elem def singletonSet2(elem: Int): Set = Set(elem) println(contains(singletonSet1(5), 5)) println(contains(singletonSet2(5), 5)) println(singletonSet2(42).getClass) } truetrue, 而不是像class scala.collection.immutable.Set$Set1这样的东西,正如你所期望的那样。

更令人困惑的是,Int => Boolean也有效,因为scala的标准集contains(singletoSet2(5), 5) 实现了Set[A],可以看出{ {3}}