sid*_*yll 12 haskell functional-programming currying partial-application operator-sections
虽然我对数学意义上的currying有一点了解,但部分应用中缀函数是一个新概念,我在深入研究" 了解你是一个很好的Haskell "一书后发现了这个概念.
鉴于此功能:
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
Run Code Online (Sandbox Code Playgroud)
作者以一种有趣的方式使用它:
ghci> applyTwice (++ [0]) [1]
[1,0,0]
ghci> applyTwice ([0] ++) [1]
[0,0,1]
Run Code Online (Sandbox Code Playgroud)
在这里我可以清楚地看到,结果函数传递了不同的参数,这不会通过正常的方式发生,因为它是一个curried函数(是吗?).那么,Haskell对中缀切片有什么特殊处理吗?它对所有中缀函数都是通用的吗?
作为旁注,这是我使用Haskell和函数式编程的第一周,我还在读这本书.
Ric*_* T. 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
Run Code Online (Sandbox Code Playgroud)
Don*_*art 15
是的,这是部分语法在起作用.
段被写为( op e )或( e op ),其中op是二元运算符,e是表达式.对于二元运算符的部分应用,段是一种方便的语法.
以下身份包含:
(op e) = \ x -> x op e
(e op) = \ x -> e op x
Run Code Online (Sandbox Code Playgroud)
所有中缀运算符都可以在Haskell中的部分中使用 - 除了-由于一元否定的奇怪性.这甚至包括通过使用反引号转换为中缀的非中缀函数.您甚至可以考虑将操作员作为双面部分的正常功能的公式:
(x + y)- >(+ y)- >(+)
部分(主要是一些罕见的角落案例)被视为简单的lambdas.(/ 2)是相同的:
\x -> (x / 2)
并且与具有非交换运算符的示例(2 /)相同\x -> (2 / x).
理论上没有什么比这更令人感兴趣了.它只是部分应用中缀运算符的语法糖.它经常使代码变得更漂亮.(当然有反例.)