我最近遇到了以下代码,这让我很困扰
lowerSafeForeignCall dflags block
| (entry, middle, CmmForeignCall { .. }) <- blockSplit block
= do
-- do block stuffs
-- Block doesn't end in a safe foreign call:
| otherwise = return block
这段代码来自https://phabricator.haskell.org/rGHCb0534f78a73f972e279eed4447a5687bd6a8308e
in file compiler/cmm/CmmLayoutStack.hs
983路
我真的很想知道第二行的这个<是什么。我相信>lowerSafeForeignCall是一个函数,| 和">否则"表示此函数使用防护装置。所以
(entry, middle, CmmForeignCall { .. }) <- blockSplit block
必须是布尔类型。但是<-在任何做块之外。我在网上做了一些搜索,但仍然没有关于这种用法的线索。
这是一个模式防护:
防护→ Pat
<-
Infixexp (模式防护(
[...]
守卫具有以下形式之一:
- 模式防护的形式是
p <- e
,其中 p 是 t 类型的模式(参见第 3.17 节(,e 是表达式类型 t。如果表达式 e 与模式 p 匹配,它们就会成功,并将模式的绑定引入环境。
当普通守卫仅限于布尔检查时,模式守卫可以匹配任意模式并定义局部变量。(在您的情况下,entry
、middle
和CmmForeignCall
的内容将直接在函数体中可用。
您可以将布尔守卫视为等效于模式为 True
的模式守卫:
| expr
作品像
| True <- expr
这是一个模式守卫[Haskell-wiki]。由于哈斯克尔'10,后卫是预选赛的名单。限定符可以是条件(如旧守卫(和模式守卫。
因此,Haskell将(懒惰地(评估箭头<-
右侧的表达式,并将其与箭头左侧的图案相匹配。如果成功了,那么守卫(也就是守卫的那部分(就成功了。如果守卫的所有部分都成功,则规则"触发"。
在此特定情况下,模式中唯一可能失败的部分是 3 元组的第三项不是CmmForeignCall
数据构造函数。此外,通过使用这种模式保护,我们当然可以在表达式的主体中使用entry
,middle
。