【问题标题】:Best use cases for currying functions and partially applied functions in scala [duplicate]scala中柯里化函数和部分应用函数的最佳用例[重复]
【发布时间】:2017-09-21 15:31:03
【问题描述】:

我正在尝试学习 Scala,但我很困惑何时使用柯里化函数而不是部分应用的函数。

我很确定这些概念并不是多余的,但我看不出不同方法的真正目的。

我正在试验这段代码:

解决方案使用柯里化:

object CurryTest extends App {

  def filter(xs: List[Int], p: Int => Boolean): List[Int] =
    if (xs.isEmpty) xs
    else if (p(xs.head)) xs.head :: filter(xs.tail, p)
    else filter(xs.tail, p)

  def modN(n: Int)(x: Int) = ((x % n) == 0)

  val nums = List(1, 2, 3, 4, 5, 6, 7, 8)

  println(filter(nums, modN(2)))
  println(filter(nums, modN(3)))
}

解决方案使用部分应用函数:

object PartialFunctionTest extends App {

  def filter(xs: List[Int], p: Int => Boolean): List[Int] =
    if (xs.isEmpty) xs
    else if (p(xs.head)) xs.head :: filter(xs.tail, p)
    else filter(xs.tail, p)

  def modN(n: Int, x: Int) = ((x % n) == 0)

  val nums = List(1, 2, 3, 4, 5, 6, 7, 8)

  println(filter(nums, modN(2,_)))
  println(filter(nums, modN(3,_)))
}

两者都给出相同的结果:

List(2, 4, 6, 8)
List(3, 6)

这些不同的方法是否等效?

有人可以启发我,每种情况的最佳用例是什么?

【问题讨论】:

标签: scala currying partial-application


【解决方案1】:

这主要是一种风格选择。在您的情况下,它没有真正的区别,但我认为具有多个参数列表的第一个替代方案看起来更好。

就风格而言,当方法打算以柯里化方式使用时,请使用柯里化函数。当您需要 curry 不是为它设计的函数时,请使用部分应用程序。

但在某些情况下,您必须使用其中一种。例如,多个参数列表允许您在两个列表中都使用 var args

def ex1(ints: Int*)(strings: String*)

如果你有泛型类型,这些类型可以从一个列表流到下一个列表

def ex2[A](input: A)(func: A => A): A = func(input)
ex2(1)(x => "Hello " + x) //compile error, A is Int from first parameter list

def ex2a[A](input: A, func: A => A): A = func(input)
ex2a(1, x => "Hello " + x) //compiles and returns "Hello 1",  A is Any because all parameters in the same list are used to determine it's type

在某些情况下,您可能需要使用部分应用程序。例如,在案例类构造函数中,如果您尝试对其进行柯里化,则只有第一个参数列表成为案例类字段的一部分。

case class ex3(a: Int, b:Int)
ex3(1, 2) == ex3(1,3) //false

val y: Int => ex3 = ex3(1,_)

y(2) == y(2) //true
y(2) == y(3) //false

case class ex3a(a: Int)(b:Int)

ex3a(1)(2) == ex3a(1)(3) //true

val x: Int => ex3a = ex3a(1)

x(1) == x(1) //true
x(1) == x(2) //true

【讨论】:

  • Currying 和部分应用的函数是不一样的,而且不仅仅是一种样式选择。柯里化函数是对 N-arity 产生 N * 1 - arity 函数的函数,这意味着函数采用单个参数,产生 1 arity 的附加函数。一个部分应用的函数会产生一个新函数,其中 n - m 是参数的数量。
猜你喜欢
  • 2012-03-14
  • 2012-12-27
  • 1970-01-01
  • 2021-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-22
  • 1970-01-01
相关资源
最近更新 更多