【问题标题】:How does this where syntax works?where 语法是如何工作的?
【发布时间】:2017-06-11 13:50:35
【问题描述】:

我正在从 GitHub 研究这个解决方案,以解决 Haskell from First Principles 书中提出的问题。这是代码

data Nat =
    Zero
  | Succ Nat deriving (Eq, Show)

integerToNat :: Integer -> Maybe Nat
integerToNat i
  | i < 0  = Nothing
  | i == 0 = Just Zero
  | i > 0  = Just (Succ x) where (Just x) = integerToNat $ i-1

我很困惑

其中 (Just x) = integerToNat $ i-1

我以为我只能将表达式分配给where 中的标识符。但看起来(Just x) 解包了分配的表达式的值并将x 分配回(Succ x)

有人能解释一下为什么会这样吗?

【问题讨论】:

  • 为什么不呢? ;) 你基本上是正确的,它有点解压rhs。这与适用于函数定义的模式匹配机制相同,例如 natToInteger Zero = 0; natToInteger (Succ x) = 1 + natToInteger x
  • 请记住,即使where Just x = ... 通过模式匹配定义了x,这也可能很危险:当要求x 时,如果模式不匹配(例如,因为递归调用返回Nothing),将引发运行时错误,使整个程序崩溃。当然,在这里它永远不会发生,但程序员有责任确保这一点。

标签: haskell syntax


【解决方案1】:

Haskell context free syntax,有一个关于函数右手边(rhs)的条目:

rhs &rightarrow; =exp [wheredecls]
| gdrhs [where 声明]

这意味着我们必须查看decls 以获取where 语法。 declsdecls 的序列:

decls &rightarrow; { decl1; ...; decln }

decl 又有两个可能的规则:

decl&rightarrow;性别
| (funlhs | pat) 右耳

这意味着我们可以在where 子句的左侧声明模式(pat)。实际上在where a = 1 中,a 可以说已经是一种模式了。该模式由一个变量组成。但是where 子句左侧的构造函数、别名运算符等都是可以接受的。

模式可以是变量、通用构造函数、限定构造函数、文字、通配符、列表模式、元组模式、无可辩驳的模式等。然后可以找到模式的整个语法here。所以简而言之,它就像函数头部的模式匹配一​​样工作。

【讨论】:

  • 知道了。这意味着我可以写得更少,因为 where 支持构造函数匹配...感谢您的澄清。
  • @NirvinM:是的,where 子句的工作方式类似于函数头部的模式匹配系统。
猜你喜欢
  • 2021-06-15
  • 2011-02-12
  • 1970-01-01
  • 2019-02-15
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
相关资源
最近更新 更多