这是我书中的一段代码,我不确定匹配是如何工作的,因为似乎第一个案例匹配了所有东西。以下是Ocaml向我抛出的警告:
# let zero = 0;;
# let one = 1;;
# let rec fib i =
match i with
zero -> zero
| one -> one
| j -> fib (j - 2) + fib (j - 1);;
Characters 57-60:
Warning: this match case is unused.
Characters 74-75:
Warning: this match case is unused.
| one -> one
^^^
| j -> fib (j - 2) + fib (j - 1);;
^
val fib : int -> int = <fun>
# fib 1;;
- : int = 1
# fib 2002;;
- : int = 2002发布于 2012-01-30 11:11:41
这是一个相当常见的混乱来源。从本质上讲,您希望将模式看作是由常量(如0和1)和由该模式绑定的标识符构建的。
当标识符出现在模式中时,它会匹配任何内容,并将匹配的值绑定到该标识符。模式中的标识符不引用与该标识符相关联的任何先前的值。因此,您的模式将始终与第一种情况相匹配,并将zero绑定到i的值。
您可以想象,您希望能够为常量值指定名称,然后在模式中使用名称而不是常量。然而,OCaml (像其他FP语言一样)不是这样工作的。一个优点(在我看来)是它让事情变得简单。
发布于 2012-01-31 15:48:24
我想我应该补充说,如果您将代码重写为以下代码,它将工作得很好:
# let zero = 0;;
# let one = 1;;
# let rec fib i =
match i with
0 -> zero
| 1 -> one
| j -> fib (j - 2) + fib (j - 1);;基本问题(正如在另一个答案中解释得相当好)是,您可以创建与全局变量同名的新局部变量,并且在匹配的左侧使用任何变量名称只会创建一个具有该名称的新局部变量,并用匹配的任何内容填充它。正如j是一个新的局部变量,它包含所有匹配的内容一样,zero也是如此。Ocaml忽略了以前在更大的作用域中声明它的事实(这就是为什么您可以愉快地编写如下内容
let x = 1;;
let x = 2 in let x = 3 in x;;其结果为3。
https://stackoverflow.com/questions/9058849
复制相似问题