左箭头<-在do块外是什么意思?

时间:2019-05-31 10:36:11

标签: haskell ghc guard-clause pattern-guards

我最近遇到了以下代码,这让我很困扰

#pod 'FacebookCore'
#pod 'FacebookLogin'

这段代码来自 https://phabricator.haskell.org/rGHCb0534f78a73f972e279eed4447a5687bd6a8308e

在文件editor / cmm / CmmLayoutStack.hs中

第983行

我真的很想知道第二行是什么<-。 我相信 lowerSafeForeignCall 是一个函数,并且 | 和'否则'表示该函数使用了防护功能。所以

lowerSafeForeignCall dflags block
| (entry, middle, CmmForeignCall { .. }) <- blockSplit block
= do
 -- do block stuffs
 -- Block doesn't end in a safe foreign call:
| otherwise = return block

必须是布尔类型。但是<-在任何do块之外。 我在网上做了一些搜索,但仍然没有关于此用法的任何线索。

2 个答案:

答案 0 :(得分:11)

那是pattern guard

  

guard pat p <- e infixexp (模式保护)

[...]

  

后卫具有以下形式之一:

     
      
  • 模式卫士的格式为entry,其中 p 是类型为 t <的模式(请参见第3.17节) / em>和 e 是表达式类型 t 。如果表达式 e 与模式 p 匹配,它们将成功,并将模式的绑定引入环境。
  •   

在常规防护只限于布尔检查的情况下,模式防护可以与任意模式匹配并定义局部变量。 (在您的情况下,middleCmmForeignCallTrue的内容将直接在函数主体中提供。)

您可以认为布尔值守卫与模式为| expr 的模式守卫等效:

| True <- expr

{{1}}

答案 1 :(得分:8)

这是pattern guard [Haskell-wiki]。自从Haskell'10开始,后卫便是资格赛的名单。限定词可以是条件(例如在旧的后卫中)和模式后卫

因此,Haskell将(懒惰地)评估箭头<-右侧的表达式,并使其与箭头左侧的图案匹配。如果成功,则后卫(后卫的那部分)将成功。如果后卫的所有部分都成功,则规则“开火”。

在这种特定情况下,模式中唯一可能失败的部分是三元组的第三项不是CmmForeignCall数据构造函数。此外,通过使用此模式防护,我们当然可以在表达式的主体中使用entrymiddle