oop - 柯里化(Currying)和重载一样吗?

标签 oop functional-programming overloading currying

函数式编程的柯里化与面向对象编程的重载相同吗?如果不是,为什么? (如果可能的话,附上例子)

塔克斯

最佳答案

柯里化不是函数式编程特有的,重载也不是面向对象编程特有的。

“柯里化”是使用函数,您可以向这些函数传递比获得剩余参数的函数所需的更少的参数。即,如果我们有一个函数 plus,它接受两个整数参数并返回它们的和,那么我们可以将单个参数 1 传递给 plus,结果是一个将事物加 1 的函数。

在 Haskellish 语法中(通过邻接函数应用):

plusOne = plusCurried 1
three = plusOne 2
four = plusCurried 2 2
five = plusUncurried 2 3

在模糊的 Cish 语法中(通过括号使用函数应用程序):
plusOne = plusCurried(1)
three = plusOne(2)
four = plusCurried(2)(2)
five = plusUncurried(2, 3)

您可以在这两个示例中看到 plusCurried 仅在 1 个参数上调用,结果是可以绑定(bind)到变量然后在另一个参数上调用的内容。您将柯里化视为函数式编程概念的原因是,它在语法通过邻接应用的函数式语言中最常用,因为在这种语法中柯里化变得非常自然。 plusCurriedplusUncurried 在 Haskellish 语法中定义 fourfive 的应用程序合并变得完全无法区分,因此您可以始终将所有函数完全柯里化(即,每个函数都是它们的一个函数,只有一个参数,返回可以应用于更多参数的其他函数)。而在通过括号参数列表应用的 Cish 语法中, fourfive 的定义看起来完全不同,因此您需要区分 plusCurriedplusUncurried 。此外,导致今天面向对象语言的命令式语言从来没有能力将函数绑定(bind)到变量或将它们传递给其他函数(这被称为具有一流的函数),如果没有这种功能,您实际上什么也做不了 使用柯里化函数执行 ,而不是在所有参数上调用它,因此使用它们毫无意义。今天的一些面向对象语言仍然没有一流的功能,或者最近才获得它们。

术语柯里化还指将具有多个参数的函数转换为一个接受单个参数并返回另一个函数的过程(该函数接受一个参数,并且可能返回另一个函数......),而“取消柯里化”可以指到进行反向转换的过程。

重载是一个完全不相关的概念。重载名称意味着给出具有不同特征(参数类型、参数数量、返回类型等)的多个定义,并让编译器通过名称出现的上下文来解析名称的给定外观所指的定义。

一个相当明显的例子是,我们可以定义 plus 来添加整数,但也可以使用相同的名称 plus 来添加浮点数,我们可能会使用它来连接字符串、数组、列表等,或者添加向量或矩阵。所有这些都有非常不同的实现,就语言实现而言,它们彼此无关,但我们只是碰巧给它们起了相同的名字。然后编译器负责确定 plus stringA stringB 应该调用字符串 plus(并返回一个字符串),而 plus intX intY 应该调用整数 plus(并返回一个整数)。

同样,这个概念是“OO 概念”而不是函数式编程概念没有内在的原因。碰巧它很自然地适用于开发的静态类型的面向对象语言;如果您已经在解决调用该方法的对象要调用的方法,那么允许更一般的重载是一个小小的延伸。完全临时重载(您只做多次定义相同的名称并信任编译器来解决它)在具有一流函数的语言中不太适合,因为当您将重载名称作为函数本身,您没有调用上下文来帮助您确定预期的定义(如果程序员真正想要的是传递所有重载的定义,他们可能会感到困惑)。 Haskell 开发了类型类作为使用重载的更原则性的方式;这些实际上确实允许您一次传递所有重载定义,并且还允许类型系统表达类型有点像“定义了函数 fg 的任何类型”。

总之:
  • 柯里化和重载完全无关
  • 柯里化是关于将函数应用于比它们需要的更少的参数,以获得剩余参数的函数
  • 重载是关于为同名提供多个定义,并让编译器在每次使用名称时选择使用哪个定义
  • 柯里化和重载都不是函数式编程或面向对象编程所特有的;由于语言的发展方式,它们每个只是碰巧在一种或另一种历史语言中更普遍,导致它们在一种语言中更有用或更明显
  • 关于oop - 柯里化(Currying)和重载一样吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10610665/

    相关文章:

    c++ - 将类型信息传递给函数代替虚拟模板函数 C++

    c# - 在 C# 中使用工厂设计模式的示例

    f# - 初学者 : Expressions in F#

    haskell - Haskell 中的旋转参数

    javascript - Function.call、Function.prototype.call、Function.prototype.call.call 和 Function.prototype.call.call.call 之间的区别

    java - 通过动态转换重载方法

    c - C 中是否存在某种形式的函数重载?

    c# - 单元测试 DateTime.Now

    php - 线程注释类给我数组错误

    python - 为什么这在 Python 中有效?创建一个实例,在该类中设置一个不存在的属性,然后通过实例打印该属性