部分应用中缀运算符引发的困惑

3

我正在阅读一份关于Haskell的在线指南,对中缀运算符和过滤器的组合感到好奇。

假设你有一个函数,例如:

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

这将返回[6,10],这似乎是筛选应该工作的直观方式。

然而,执行以下操作

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

返回一个空列表(这仍然有意义,(>)检查其第一个参数是否大于第二个参数)。
然而,filter通常被定义为类似于:
filter :: (a -> Bool) -> [a] -> [a]  
filter _ [] = []  
filter p (x:xs)   
    | p x       = x : filter p xs  
    | otherwise = filter p xs

当类型系统知道它有一个中缀运算符时,大多数这些中缀运算符是这样编写的,部分应用的函数需要原始前缀函数的前导参数吗?例如,中缀运算符 > 是否定义为类似于以下代码(语法可能有误):
infix> :: Int -> Int-> Bool
infix> x y = (>) y x
x infix> y = (>) x y

抱歉,如果这个问题不太有意义的话。我感觉自己在理解部分应用中缺少一些基础知识,尤其是当p是一个部分应用的中缀运算符时,它是如何被评估的。

1个回答

10

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

第一种被称为

,它的形式为(op exp)(exp op),其中op是中缀运算符,exp是另一个表达式。Section将一个参数应用于缺失的一侧,因此(>5)4=(4>5)(5>)4=(5>4)。换句话说,(>5)等价于\x -> x > 5

((>) 5)中,(>)是中缀运算符>转换为表达式。((>) 5)然后将5应用于函数(>),得到一个接受下一个参数的新函数。如果我们应用该参数,例如(>) 5 4,我们将得到(5 > 4)的前缀等价形式。

将中缀运算符转换为可以使用前缀的表达式对所有中缀运算符都适用。你也可以反过来将标识符转换为中缀运算符,即:

`foo`

你甚至可以说:

(`foo`)

将其转换回表达式。


3
谢谢。这为我消除了一个困惑点。所以,"sections" 本质上是一种句法便利结构,用于将参数映射到中缀运算符的正确位置? - Saedeas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接