Haskell中的运算符与匿名函数优先级

亚历杭德罗·纳瓦斯(Alejandro Navas)

在Haskell中,以下表达式:

 a \b -> c $ d

或者是

•无效

(a (\b ->c)) d

(a (\b -> (c d))

又为什么呢

乔恩·珀迪

在原始Haskell中这是无效的,因为没有中间运算符,lambda不能直接用作函数的参数。正确的版本需要使用$或加上括号:

a   \b -> c $ d
a $ \b -> c $ d
a ( \b -> c $ d )

然而,有一个拉姆达(或没有根本的原因caseifdo,或let表达)不应该被允许存在,因为它不是模棱两可。所述BlockArguments延伸部(在加入GHC 8.6.1)允许这些语法结构直接作为函数的参数。启用该选项后,其解析与上面相同,如下所示:

(a (\b -> (c $ d))

之所以不能将其解析为*的原因(a (\b -> c)) d是,Laskda的范围在Haskell报告§3中定义为尽可能向右扩展(添加了强调):

关于lambda抽象,let表达式和条件语句的范围,语法是模棱两可这些规则中的每一个都尽可能向右延伸的元规则解决了歧义

换句话说,lambda的主体可以被认为比任何其他表达式具有更低的优先级。这种表示法是直接从演算借用,其中一个λ bÇ d是相同的(一个(λ b。(C ^ d)))。

请注意,我并没有删除$这里:这两个表达式是不同的,即使它们得出的结果相同:

f x
f $ x

首先是函数f在参数上的应用x; 第二个是运算符($)对参数f和的应用x像所有infix运算符一样,它是常规前缀函数调用的语法糖:

($) f x

($)被定义为具有最低运算符优先级的右关联运算符(即x $ y $ z= x $ (y $ z)不是* (x $ y) $ z),且声明infixr 0位于Prelude您可以使用GHCi中:info(或:i)命令查看有关运算符的信息

> :info $
($) :: (a -> b) -> a -> b   -- Defined in ‘GHC.Base’
infixr 0 $

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章