在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 )
然而,有一个拉姆达(或没有根本的原因case
,if
,do
,或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] 删除。
我来说两句