Haskell 一个部分是咖喱的结果吗?
在Hutton的Haskell编程中 通常,如果Haskell 一个部分是咖喱的结果吗?,haskell,operators,currying,partial-application,operator-sections,Haskell,Operators,Currying,Partial Application,Operator Sections,在Hutton的Haskell编程中 通常,如果是运算符,则参数x的形式为(#)、(x#)、和(#y),且 y称为节,其作为函数的含义可以是 使用lambda表达式进行形式化,如下所示: (#) = \x -> (\y -> x # y) (x #) = \y -> x # y (# y) = \x -> x # y “节”与“咖喱”有什么区别和联系 节是对多参数函数应用curry操作的结果吗 谢谢。
是运算符,则参数x
的形式为(#)
、(x#)、和(#y)
,且
y
称为节,其作为函数的含义可以是
使用lambda表达式进行形式化,如下所示:
(#) = \x -> (\y -> x # y)
(x #) = \y -> x # y
(# y) = \x -> x # y
“节”与“咖喱”有什么区别和联系
节是对多参数函数应用curry操作的结果吗
谢谢。节只是将中缀运算符应用于单个参数的特殊语法(#y)
是两者中更有用的,因为(x#)
相当于(#)x
(它只是以通常的方式将中缀运算符作为函数应用于单个参数)。左侧部分和右侧部分是将中缀运算符部分应用于单个参数的语法设备(另请参见)。为了准确起见,我们应该注意,curry与partial application不是一回事:
- curry是将一个接受N个参数的函数转换为一个接受单个参数并返回一个接受N-1个参数的函数
- 部分应用程序正在生成一个函数,该函数通过提供一个参数从一个函数中获取N-1个参数
在哈斯克尔,一切都是咖喱;所有函数都只接受一个参数(即使Haskell中的未剪切函数也接受一个元组,严格来说,这是一个参数——您可能需要使用curry
和uncurry
函数来了解其工作原理)。尽管如此,我们还是经常非正式地认为返回函数的函数是多个参数的函数。从这个角度来看,默认情况下使用curry的一个很好的结果是,函数对其第一个参数的部分应用变得微不足道:例如,elem
获取一个值和一个容器,并测试该值是否是container的一个元素,elem“apple”
获取一个容器(由字符串组成),并测试“苹果”
是其中的一个元素
至于运算符,例如,当我们编写时
5 / 2
…我们正在将运算符/
应用于参数5
和2
。运算符也可以以前缀形式使用,而不是中缀形式:
(/) 5 2
在前缀形式中,运算符可以以通常的方式部分应用:
(/) 5
然而,这可能看起来有点尴尬——毕竟,5
这里是分子,而不是分母。我想说,在这种情况下,左边部分的语法更容易理解:
(5 /)
此外,部分应用于第二个参数,需要lambda或翻转
。对于运算符,右部分可以帮助:
(/ 2)
请注意,部分还使用通过backtick语法生成运算符的函数,因此
(`elem` ["apple", "grape", "orange"])
…获取一个字符串并测试它是否可以在[“苹果”、“葡萄”、“橘子”]
咖喱fxy=f(x,y)
uncurry g(x,y)=gxy
中找到
(+3)4=(+)43=4+3
(4+3=(+)43=4+3
节是部分应用当前函数的结果:(+3)=翻转(+)3
,(4+)=(+)4
curried函数(如g
或(+)
)一次需要一个参数。未经载波的函数(如f
)一次需要一个元组中的参数
若要部分应用未编译函数,我们必须首先将其转换为curry函数,使用curry
。若要部分应用curry函数,我们不需要做任何事情,只需将其应用于参数
curry :: ((a, b) -> c ) -> ( a -> (b -> c))
uncurry :: (a -> (b -> c)) -> ((a, b) -> c )
x :: a
g :: a -> (b -> c)
--------------------
g x :: b -> c
x :: a
f :: (a, b) -> c
---------------------------
curry f :: a -> (b -> c)
curry f x :: b -> c
一个部分正是引用的段落所说的。这与咖喱有什么关系?想象一下一种带有中缀符号的函数的语言。一个二进制函数可能看起来像(2)sub(3)
-是的,它也会伤害我的眼睛。左/右部分将是(2)sub
/sub(3)
。显然,这不适用于多参数函数。Curry和Section a之间的唯一关系是,您需要Curry函数来表示运算符节。在某种意义上,Section允许部分应用类似于前缀符号的中缀运算符,是的。(#)
也是一个节。@melpomene严格地说,我不认为它是。只谈论左节和右节;(#)
语法在中单独提到。我曾经问过,似乎没有明确的来源。如果没有严格的定义,我也不会感到惊讶;直觉上,我认为它是中缀运算符的部分应用,(#)
看起来像节,但不一定与节相关。有人可能会认为运算符“applied“to zero arguments计算“底层”函数。有点像。中缀运算符只是一种语法上的精确性;它和任何其他函数一样,只是以不同的形式编写它的应用程序。要将反引号拖到其中(其中加3 5和3`plus`5
是等效的),请编写(3+)
就像你可以写加3
一样。你也可以写(+5)
,在没有直接等价物的地方使用前缀符号,而不使用flip
,(+5)
与flip+5
@Tim相同。你为什么发表这个评论?这只是重复你的问题。