使用中缀函数的部分应用程序

时间:2012-04-12 20:28:18

标签: haskell functional-programming currying partial-application operator-sections

虽然我对数学意义上的曲线有一点了解,但部分原因 应用中缀功能是我在潜水后发现的一个新概念 进入书Learn You a Haskell for Great Good

鉴于此功能:

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和函数式编程的第一周, 我还在读这本书。

3 个答案:

答案 0 :(得分:18)

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

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

了解反引号(``)的用法很有用,它可以让你在中缀运算符中用两个参数转换任何标准函数:

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

答案 1 :(得分:15)

是的,这是the section syntax在工作。

节被写为( op e )( e op ),其中op是二元运算符,e是表达式。对于二元运算符的部分应用,段是一种方便的语法。

以下身份确定:

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

答案 2 :(得分:5)

所有中缀运算符都可以在Haskell中的部分中使用 - 除-之外由于一元否定的奇怪性。这甚至包括通过使用反引号转换为中缀的非中缀函数。您甚至可以考虑将操作员作为正常功能的公式作为双面部分:

  

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

部分(主要是一些罕见的角落案例)被视为简单的lambdas。 (/ 2)与以下内容相同:

  

\x -> (x / 2)

对于具有非交换运算符的示例,

(2 /)\x -> (2 / x)相同。

理论上没有什么比这更令人感兴趣了。它只是部分应用中缀运算符的语法糖。它经常使代码变得更漂亮。 (当然有反例。)