跳转到内容

Haskell/解决方案/模式匹配

来自维基教科书,开放的书籍,为开放的世界

← 返回模式匹配

匹配字面量值

[编辑 | 编辑源代码]
练习
  1. 在 GHCi 中测试上面有缺陷的 h 函数,使用等于 1 和不同于 1 的参数。然后解释错误发生的原因。
  2. 在本节关于用字面量值进行模式匹配中,我们没有提到布尔值 TrueFalse,但我们也可以用它们进行模式匹配,如 下一步 章中所示。你能猜出我们为什么省略它们吗?(提示:我们写布尔值的方式有什么独特之处吗?)

1.

在用于模式匹配时,像 h 中的 k 这样的简单变量名

h k = True

k 绑定到 h 的参数,并且至关重要的是,匹配任何东西。由于我们在等式右侧没有使用绑定的 k 变量,因此在这个函数中,这个定义的效果与

h _ = True

相同,这就是 GHC/GHCi 会抱怨模式重叠,以及为什么 h 的第二个等式被忽略。此外,在函数外部定义的 k = 1 定义不会影响发生的事情 - 用于模式匹配的 k 具有局部作用域(h 等式的作用域),并且与其他 k 无关。

2.

Bool 不是字面量值;相反,它是一个代数数据类型,就像我们在上一章中首次遇到的那样。本质上,它在 Prelude 中的定义等同于

data  Bool  =  False | True

FalseTrue 是无参数构造函数;这就是为什么它们的名字以大写字母开头。

语法技巧

[编辑 | 编辑源代码]
练习
实现 scanr,如 列表 III 中的练习所示,但这次使用 as 模式。


myScanr step zero [] = [zero]
myScanr step zero (x:xs) = (step x y):ys
    where ys@(y:_) = myScanr step zero xs

你可能在第一个版本的练习中使用了 head 而不是 as 模式;但是,在这里,我们没有在 ys 的模式中匹配空列表。在这种特定情况下,两种解决方案都不是不安全的,因为 myScanr 的结果永远不会是空列表。然而,模式匹配仍然比 head 更好,因为它更清楚地表明我们选择不处理空列表情况。

华夏公益教科书