-->

使用Scala的部分功能 - 它是如何工作的?使用Scala的部分功能 - 它是如何工作的?(Usi

2019-05-12 20:48发布

我是新来斯卡拉,我使用的是2.9.1,而我试图让我的周围如何使用部分功能头。 我有咖喱的功能有基本的了解,我知道的部分功能是有点像,他们是唯一2nary或一些这样的咖喱功能。 正如你可以告诉我有点绿色的这个。

它似乎在某些情况下,如XML过滤,能够部分功能将是非常有利的,所以我希望得到一个更好地了解如何使用它们。

我有一个使用重写规则结构的功能,但我需要它有两个参数工作,而重写规则结构只需要一个,或部分功能。 我觉得这是我想它是有帮助的案例之一。

任何意见,链接,智慧等词的欢迎!

答案至今都非常出色,并清理了一些基本的误解我。 我想他们也解释了在那里我挣扎 - 我想,也许发布一个新的问题是多一点具体的帮助,所以我会做到这一点。

Answer 1:

的部分功能是一个函数,是有效的只有这些类型的值的子集,你可能会在传递给它。 例如:

val root: PartialFunction[Double,Double] = {
  case d if (d >= 0) => math.sqrt(d)
}

scala> root.isDefinedAt(-1)
res0: Boolean = false

scala> root(3)
res1: Double = 1.7320508075688772

当你有一些知道如何检查功能是否被定义与否,这是非常有用的。 收集,例如:

scala> List(0.5, -0.2, 4).collect(root)   // List of _only roots which are defined_
res2: List[Double] = List(0.7071067811865476, 2.0)

不会帮助你把两个参数,你真的想要一个。

相反, 部分应用的功能就是它的一些参数已经被填充的功能。

def add(i: Int, j: Int) = i + j
val add5 = add(_: Int,5)

现在你只需要一个参数 - 事到5增加 - 而不是两个:

scala> add5(2)
res3: Int = 7

你可以从这个例子来看看如何使用它。

但是,如果你需要指定的两个参数,这仍然不能做到这一点-说你要使用map ,比如,你需要给它一个参数的功能,但你希望它添加两个不同的东西。 好了,那么你就可以

val addTupled = (add _).tupled

这将部分应用功能(真的,只是创建一个函数的方法的,因为什么也没有填写),然后单独的参数组合成一个元组。 现在你可以在需要一个参数(假定该类型是正确的)的地方使用此:

scala> List((1,2), (4,5), (3,8)).map(addTupled)
res4: List[Int] = List(3, 9, 11)

相比之下, 钻营是不同的又一次; 它原来的形式的功能(A,B) => CA => B => C 。 也就是说,给定的多个参数的函数,它会产生的每一个参数,并返回一个链中的一个函数链较短(你可以把它在一个时间为部分应用一个参数)。

val addCurried = (add _).curried

scala> List(1,4,3).map(addCurried)
res5: List[Int => Int] = List(<function1>, <function1>, <function1>)

scala> res5.head(2)   // is the first function, should add 1
res6: Int = 3

scala> res5.tail.head(5)   // Second function should add 4
res7: Int = 9

scala> res5.last(8)  // Third function should add 3
res8: Int = 11


Answer 2:

雷克斯·科尔的解释是非常好 - 而且毫不奇怪无论是。 问题显然是混合了部分应用功能 部分的功能 。 不管它是值得的,我做了同样的困惑我自己,当我得知斯卡拉。

然而,因为这个问题确实提请注意局部的功能,我想讲他们的一点。

很多人说,部分函数是不是所有的输入定义的函数,这就是数学的事实,但不是斯卡拉。 Scala中,功能可以不被用于所有输入任一所定义。 事实上,由于从功能部分功能的继承,然后功能包括所有的部分功能以及,使该不可避免的。

其他提及的方法isDefinedAt ,这确实是有差别,但一个主要是关于执行。 这是如此真实的斯卡拉2.10可能会用一个“快部分功能”,它不依赖于发布isDefinedAt

而一些人甚至暗示, apply对部分功能做的方法比不同的东西apply方法的功能,如仅被定义的输入执行-这不能从真理更远。 该apply方法是完全一样的

什么部分功能真正回落到另一种方法: orElse 。 这总结了部分功能大大优于所有用例isDefinedAt ,因为部分功能真的是这样做的以下情况之一:

  • 链部分功能(这是orElse一样),使得输入将在每个部分功能被尝试,直到它们中的一个相匹配。
  • 做一些不同的,如果部分功能不匹配,而不是抛出一个异常,也就是如果您将使用不同的事情会发生什么, orElse

我不是说一切都可以在以下方面可以轻松实现orElse ,你要知道。 我只是说,部分功能是关于当输入为没有定义做别的事情。



文章来源: Using partial functions in Scala - how does it work?