首页 / 知识
关于函数式编程:什么是“固化”?
2023-04-13 17:40:00

What is 'Currying'?我在几篇文章和博客中都看到过关于咖喱函数的引用,但是我找不到很好的解释(或者至少有一个合理的解释!) 咖喱化是指将一个包含多个参数的函数分解为一系列仅包含一个参数的函数。这是JavaScript中的示例:
该函数接受两个参数a和b并返回它们的总和。现在,我们将使用此函数:
这是一个接受一个参数a的函数,并返回接受另一个参数b的函数,该函数返回其和。
第一条语句返回7,就像add(3,4)语句一样。第二条语句定义了一个名为add3的新函数,该函数会将3加到其参数中。这就是某些人所谓的关闭。第三条语句使用add3操作将3加到4,结果再次产生7。 在函数的代数中,处理带有多个参数(或等效的一个参数为N元组)的函数有些微不足道-但是,正如Moses Sch?nfinkel(以及独立的Haskell Curry)证明的那样,它是不需要的:您需要的只是带有一个参数的函数。
那么,您如何处理自然表达为 像往常一样,维基百科对此有一个很好的总结条目,其中包含许多有用的指针(可能包括与您喜欢的语言有关的指针;-)以及更为严格的数学处理方法。 这是一个具体的例子: 假设您有一个计算作用在物体上的重力的函数。如果您不知道公式,可以在这里找到。此函数将三个必需参数作为参数。 现在,在地球上,您只想计算该星球上物体的力。用功能语言,您可以将地球质量传递给功能,然后对其进行部分评估。您会得到的是另一个仅使用两个参数并计算地球上物体的重力的函数。这称为"咖喱"。 Currying是一种可以应用于函数的转换,以使它们比以前少使用一个参数。 例如,在F#中,您可以这样定义一个函数:
在这里,函数f接受参数x,y和z并将它们相加在一起:
返回6。 因此,根据我们的定义,我们可以为f定义curry函数:-
其中'fun x-> f x'是Lambda函数,等效于C#中的x => f(x)。该函数输入您要咖喱的函数,并返回一个带有单个参数的函数,并返回将第一个参数设置为输入参数的指定函数。 使用前面的示例,我们可以得到f的咖喱:-
然后,我们可以执行以下操作:
它为我们提供了与f1 y z = 1 + y + z等价的函数f1。这意味着我们可以执行以下操作:
返回6。 此过程通常与"部分功能应用程序"混淆,可以这样定义:
尽管我们可以将其扩展为多个参数,即:-
部分应用程序将使用该函数和参数,并返回一个需要一个或多个更少参数的函数,并且如前两个示例所示,该函数直接在标准F#函数定义中实现,因此我们可以达到上述结果:
这将返回结果6。 结论:- currying和部分函数应用程序之间的区别在于: Currying具有一个函数,并提供一个接受单个参数的新函数,并返回其第一个参数设置为该参数的指定函数。这使我们可以将具有多个参数的函数表示为一系列单参数函数。例:-
局部函数应用程序更直接-它接受一个函数和一个或多个参数,然后返回将前n个参数设置为指定的n个参数的函数。例:-
它可以是使用功能来实现其他功能的一种方式。 在javascript中:
将允许我们这样称呼它:
运行此命令时,
这意味着我们将返回此函数:
所以当你打电话
你真的在打电话:
因此,如果您这样做:
它与:
因此,我们的
curried函数是重写了多个参数的函数,以便它接受第一个参数,并返回接受第二个参数的函数,依此类推。这允许几个自变量的功能部分地应用其某些初始自变量。 这是Python中的一个玩具示例:
(只需通过+使用串联,以避免非Python程序员分心。) 编辑添加:
参见http://docs.python.org/library/functools.html?highlight=partial#functools.partial,
咖喱化将函数从可调用的 否则,当您分解一个将多个参数合并为一部分参数的函数时,就会遇到麻烦。 从字面上看,currying是功能的转换:从一种调用方式转换为另一种调用方式。在JavaScript中,我们通常做一个包装来保留原始功能。 咖喱不会调用函数。它只是改变了它。
让我们创建咖喱函数,对两个参数的函数执行curring。换句话说,两个参数
如您所见,该实现是一系列包装器。
如果您了解
在Clojure中,
您可能知道
让我们使用
在这里,我们返回另一个已将1加载到
现在,假设该语言是否足够聪明,可以内省地理解
这是某些语言的行为方式。当人们希望将功能组合成更大的转换时,它特别有用。这将导致换能器。
正如所有其他答案一样,currying有助于创建部分应用的功能。 Javascript不提供对自动执行的本机支持。因此,上面提供的示例可能对实际编码没有帮助。 livescript中有一个很好的例子(本质上是编译成js)
在上面的示例中,当您没有给出任何参数时,livescript为您生成新的咖喱函数(双精度)
我发现本文及其引用的文章对更好地理解curring很有用: 正如其他人提到的那样,这只是拥有一个参数函数的一种方式。 这很有用,因为您不必假设要传入多少个参数,因此您不需要2个参数,3个参数和4个参数函数。 Curry可以简化您的代码。这是使用此功能的主要原因之一。咖喱化是将接受n个参数的函数转换为仅接受一个参数的n个函数的过程。 原理是使用闭包(closure)属性传递所传递函数的参数,将其存储在另一个函数中并将其视为返回值,这些函数形成一个链,最后的参数传递给完成操作。 这样的好处是它可以通过一次处理一个参数来简化参数的处理,这也可以提高程序的灵活性和可读性。这也使程序更易于管理。同样,将代码分成较小的部分将使其易于重用。 例如:
我也可以
这对于使复杂的代码变得整洁并处理不同步的方法等非常有用。 currying的一个示例是拥有函数时,您目前仅知道其中一个参数: 例如:
在这里,由于将回调发送给
curried函数应用于多个参数列表,而不仅仅是
这是一个常规的非咖喱函数,它添加了两个Int
这是类似的功能。代替
这里发生的是,当您调用
这是一个名为
将1应用于第一个功能-换句话说,调用第一个功能
将2应用于第二个函数将产生结果:
在这里,您可以找到有关C#中的currying实现的简单说明。在评论中,我试图说明如何使用currying:
这是使用n no的函数的通用和最短版本的示例。的参数。
这等效于partial在python中所做的工作。当我们想将通用函数用于特定目的时,可以使用这种机制来修复参数的子集。 |
最新内容
相关内容
linux各种命令的解释?
linux各种命令的解释?,地址,工作,系统,信息,命令,目录,时间,管理,控制台,常用命令,linux的常用命令有哪些呢???希望带上解释date:打印或者设置linux路径命令解释?
linux路径命令解释?,系统,信息,设备,数据,工具,命令,文件,标准,发行,时间,linux查看路径命令1、linux命令如果记不得,可以使用man命令来查看某linux查询函数命令?
linux查询函数命令?,系统,信息,名称,标准,函数,百度,代码,名字,最新,实时,Linux下查找一个函数在哪个库文件中1、默认状态下,gcc并不搜索数学库linux进程命令解释?
linux进程命令解释?,系统,状态,基础,进程,信息,时间,命令,实时,软件,名称,Linux中用于进程显示的top命令使用实例集锦1、Top 命令输出: 首先,让linux关机命令解释?
linux关机命令解释?,系统,工作,命令,时间,银河,信息,用户,级别,终端,指令,linux关机命令1、shutdown命令 shutdown命令用于安全关闭Linux系统什么是Python全局解释器锁(GIL)?
什么是Python全局解释器锁(GIL)?,数据,控制权,状态,持有,工具,时间,设计,培训,全局,线程,全局解释器锁是计算机程序设计语言解释器用于同步线Python解释器种类以及特点有哪些?
Python解释器种类以及特点有哪些?,代码,技术,培训,特点,字节,种类,速度,语言,方式,文件,当我们编写完Python代码时,我们会得到一个包含Python代深入理解python函数传参机制
深入理解python函数传参机制,培训,对象,函数,变量,类型,复本,下面,操作,机制,内存,首先需要申明的一点是,python里是没有像C和C++里那样按值传Python中的匿名函数lambda
Python中的匿名函数lambda,代码,地方,名字,主体,名称,培训,函数,表达式,赋值,语句,简述除了def语句之外,Python还提供了一种生成函数对象的表Python有哪些常用函数?
Python有哪些常用函数?,数据,函数,地址,数字,培训,工作,网络,位置,字符串,字符,Python常用函数有哪些?我想大家都比较好奇这个问题,今天小编特python的filter,lambda函数表达式
python的filter,lambda函数表达式,代码,函数,名称,培训,列表,参数,知识点,表达式,约数,元素,filter(functionorNone,sequence),其中sequence可python字符串处理函数大总结
python字符串处理函数大总结,位置,数字,异常,培训,字符串,空格,长度,两边,字母,函数,str=pythonStringfunction生成字符串变量str=pythonStri