【问题标题】:What does left arrow <- mean outside a do block?左箭头 <- 在 do 块之外是什么意思?
【发布时间】:2019-10-17 00:11:50
【问题描述】:

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

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

在文件compiler/cmm/CmmLayoutStack.hs中

第 983 行

我真的很想知道这是什么lowerSafeForeignCall 是一个函数,而 | 和 'otherwise' 表示这个函数使用了守卫。所以

(entry, middle, CmmForeignCall { .. }) <- blockSplit block

必须是 Bool 类型。但是

【问题讨论】:

标签: haskell ghc guard-clause pattern-guards


【解决方案1】:

那是pattern guard:

守卫       →   pat &lt;- infixexp     (模式守卫)

[...]

守卫具有以下形式之一:

  • 模式守卫p &lt;- e的形式,其中pt类型的模式(见3.17部分) e 是一个表达式类型t。如果表达式 e 与模式 p 匹配,它们就会成功,并将模式的绑定引入环境。

普通守卫仅限于布尔检查,模式守卫可以匹配任意模式并定义局部变量。 (在你的情况下entrymiddleCmmForeignCall 的内容将直接在函数体中可用。)

你可以认为布尔守卫等同于带有True模式的模式守卫:

| expr

| True <- expr

【讨论】:

    【解决方案2】:

    这是pattern guard [Haskell-wiki]。从 Haskell'10 开始,后卫就是一个预选赛名单。限定符可以是条件(如旧守卫)和模式守卫

    Haskell 将因此(懒惰地)评估箭头右侧的表达式 &lt;- 并旨在将其与箭头左侧的模式匹配。如果成功了,那么守卫(以及守卫的那部分)就成功了。如果守卫的所有部分都成功,则规则“触发”。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-16
      • 2013-05-01
      • 2021-03-28
      • 2018-10-08
      • 2023-03-31
      • 2015-05-15
      • 2015-03-13
      • 2012-07-16
      相关资源
      最近更新 更多