Haskell 中缀函数的部分应用

Haskell 中缀函数的部分应用,haskell,functional-programming,currying,partial-application,operator-sections,Haskell,Functional Programming,Currying,Partial Application,Operator Sections,虽然我对咖喱有一点数学意义上的理解,但部分 应用中缀函数是我潜水后发现的一个新概念 写进书中 鉴于此功能: applyTwice :: (a -> a) -> a -> a applyTwice f x = f (f x) 作者以一种有趣的方式使用它: ghci> applyTwice (++ [0]) [1] [1,0,0] ghci> applyTwice ([0] ++) [1] [0,0,1] 在这里,我可以清楚地看到结果函数有不同的参数 通过,这在

虽然我对咖喱有一点数学意义上的理解,但部分 应用中缀函数是我潜水后发现的一个新概念 写进书中

鉴于此功能:

applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
作者以一种有趣的方式使用它:

ghci> applyTwice (++ [0]) [1]  
[1,0,0]
ghci> applyTwice ([0] ++) [1]
[0,0,1]
在这里,我可以清楚地看到结果函数有不同的参数 通过,这在正常情况下是不会发生的,因为这是一个咖喱 功能(会吗?)。那么,有没有关于中缀切片的特殊处理 哈斯克尔?它对所有中缀函数都通用吗


顺便说一下,这是我在Haskell和functional programming学习的第一周,
我还在读这本书。

是的,您可以通过指定中缀运算符的左操作数或右操作数来部分应用中缀运算符,只需将另一个操作数留空(正好在您编写的两个示例中)

因此,
([0]++)
(++)[0]
\x->[0]++x
(请记住,可以通过括号将中缀运算符转换为标准函数),而
(++[0])
等于
\x->x++[0]

了解backticks(```)的用法也很有用,它使您能够在中缀运算符中使用两个参数来转换任何标准函数:

Prelude> elem 2 [1,2,3]
True
Prelude> 2 `elem` [1,2,3] -- this is the same as before
True
Prelude> let f = (`elem` [1,2,3]) -- partial application, second operand
Prelude> f 1
True
Prelude> f 4
False
Prelude> let g = (1 `elem`) -- partial application, first operand
Prelude> g [1,2]
True
Prelude> g [2,3]
False

所有中缀运算符都可以在Haskell的部分中使用-除了
-
,因为一元否定的奇异性。这甚至包括使用反勾号转换为中缀的非中缀函数。您甚至可以将运算符转换为正常函数的公式视为双面部分:

(x+y)
->
(+y)
->
(+)

切片(大多数情况下,有一些罕见的角部病例)被视为简单的lambda<代码>(/2)与以下内容相同:

\x->(x/2)

(2/)
\x->(2/x)
相同,例如使用非交换运算符

从理论上讲,这里没有什么有趣的事情。这只是部分应用中缀运算符的语法糖分。它通常会使代码更漂亮一些。(当然也有反例。)

是的,这起作用了

节写为
(op e)
(e op)
,其中op是二进制运算符,e是表达式。节是部分应用二进制运算符的方便语法

以下身份适用:

(op e)  =   \ x -> x op e
(e op)  =   \ x -> e op x

所以,我不知道Haskell,但是
(1`elem`
elem 1
一样吗?我喜欢把
(++)
看作是一个省略两个输入的部分。请注意,“一元否定的陌生性”是因为
(-1)是否是模糊的
应解释为数值文本-1或函数
\x->x-1
。Haskell的创建者选择将其解释为数字文字,并提供函数
subtract
,该函数满足
subtract x=\y->y-x
。它们还提供了充当一元减号函数的
negate
,即
negate x=-x
@ChrisTaylor:small
(-x)
转换为
否定x
,因此
(-1)
否定(从整数1)
,而不是
从整数(-1)
。当然,对于行为良好的
Num
实例,这两者应该是等价的。@hammar Ah好的,这里有一点向后的逻辑。谢谢你的更正!