是否可以对变量进行模式匹配而不是常量值:
# let x = 2 in
let y = 5 in
match 2 with
| x -> "foo"
| y -> "bar"
| _ -> "baz";;
let y = 5 in
Warning 26: unused variable y.
let x = 2 in
Warning 26: unused variable x.
| y -> "bar"
Warning 11: this match case is unused.
| _ -> "baz";;
Warning 11: this match case is unused.
- : string = "foo"
显然,使用这种语法,x -> "foo"
案例会占用一切。有没有办法使它等同于:
match 2 with
| 2 -> "foo"
| 5 -> "bar"
| _ -> "baz"
哪里匹配表达式的值是在运行时确定的?
答案 0 :(得分:6)
在我看来,when
后卫在这里是一个坏主意。初学者倾向于过度使用他们觉得方便的模式匹配语法,这导致他们的应用程序中的细微错误。对于一个会注意到“嘿,| y -> ..
这里不是我想要的人”,其他十个人会犯错,不会直接注意到。
你应该劝阻这种易出错的模式。我对初学者的个人建议是从不使用when
,而只使用模式匹配来解析归纳数据类型的值(例如列表,树,选项等)。整数上的模式匹配几乎总是错误的。
我建议改为使用if ... then .. else if .. then .. else
。
if z = x then "foo"
else if z = y then "bar"
else "baz"
何时使用when
合法?当其余案例确实受益于模式匹配(测试嵌套模式等),或者对匹配值的深度破坏产生的值执行测试时,可以理解。它通常可以通过合并两个分支并在本地使用if..then..else
来转换。
一个不方便删除的示例如下(测试结合到解构):
match foo with
| (Baz x) when pred x -> ...
| _ -> ...
答案 1 :(得分:5)
您需要when
警卫:
let x = 2 in
let y = 5 in
match 2 with
| z when z = x -> "foo"
| z when z = y -> "bar"
| _ -> "baz";;
错误消息非常有用。当你使用:
let x = 2 in
...
match 2 with
| x -> "foo"
| ...
新值x
会影响先前let-bound中的值x
,从而影响第一条错误消息。此外,由于新的x
符合所有内容,因此y
和_
以下两种模式显然是多余的。
请注意,匹配常量(match 2 with
)并不是一个好主意。
答案 2 :(得分:3)
在这里你正在寻找一个“何时”守卫:
let x = 2 in
let y = 5 in
match 2 with
| x' when x' = x -> "foo"
| y' when y' = y -> "baz"
| _ -> "baz" ;;
......虽然我不确定你为什么想要与常数匹配。