部分应用的中缀运营商的困惑

时间:2015-02-19 01:07:11

标签: haskell

所以我在线阅读Haskell指南,并对中缀运算符和过滤器的组合感到好奇。

假设您有类似

的功能
filter (>5) [6, 10, 5]

那将返回[6,10],这似乎是过滤器应该直观的方式。

然而,做

filter ((>) 5) [6, 10, 5]

返回一个空列表(这仍然有意义,(>)检查它的第一个参数是否大于第二个参数)。

但是,过滤器通常定义为

filter :: (a -> Bool) -> [a] -> [a]  
filter _ [] = []  
filter p (x:xs)   
    | p x       = x : filter p xs  
    | otherwise = filter p xs

当类型系统知道它有一个中缀运算符时,大多数中缀运算符是否写入,以便部分应用的函数需要原始前缀函数的前导参数?即是中缀>定义为(butchered syntax)

之类的东西
infix> :: Int -> Int-> Bool
infix> x y = (>) y x
x infix> y = (>) x y

很抱歉,如果这个问题没有意义,我觉得当p是部分应用的中缀运算符时,我遗漏了一些关于如何计算p x的基本内容。

1 个答案:

答案 0 :(得分:10)

(>5)((>) 5)是两种不同类型的表达。

第一个是所谓的部分。部分的格式为(op exp)(exp op),其中 op 是中缀运算符, exp 是另一个表达式。一个部分接受一个参数并将其应用于缺失的一侧,因此(>5) 4 = (4 > 5)(5>) 4 = (5 > 4)。换句话说,(>5)相当于\x -> x > 5

((>) 5)中,(>)是转换为表达式的中缀运算符>((>) 5)然后是5到函数(>)的应用,它给出了一个接受下一个参数的新函数。如果我们应用该参数,例如(>) 5 4,我们会得到相当于(5 > 4)的前缀。

将中缀运算符转换为可以使用的表达式前缀适用于所有中缀运算符。您也可以采用其他方式将标识符转换为中缀运算符,即:

`foo`

你甚至可以说:

(`foo`)

将其变回表达式。