OCaml模式与非常量匹配

Nic*_*ner 3 ocaml pattern-matching

是否可以对变量进行模式匹配而不是常量值:

# 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"
Run Code Online (Sandbox Code Playgroud)

显然,使用这种语法,x -> "foo"案例将占用一切.有没有办法使它等同于:

match 2 with
| 2 -> "foo"
| 5 -> "bar"
| _ -> "baz"
Run Code Online (Sandbox Code Playgroud)

匹配表达式的值是在运行时确定的?

gas*_*che 6

一个when后卫是一个坏主意,在这里我的意见.初学者倾向于过度使用他们觉得方便的模式匹配语法,这导致他们的应用程序中的细微错误.对于一个会注意到"嘿,| y -> ..这不是我想要的"的人,其他十个人会犯错,不会直接注意到.

你应该劝阻这种易出错的模式.我对初学者的个人建议是永远不要使用when,并且使用模式匹配来描述归纳数据类型的值(例如列表,树,选项等).整数上的模式匹配几乎总是一个错误.

我建议if ... then .. else if .. then .. else改用.

if z = x then "foo"
else if z = y then "bar"
else "baz"
Run Code Online (Sandbox Code Playgroud)

什么时候合法使用when?当其余案例确实受益于模式匹配(测试嵌套模式等),或者对匹配值的深度破坏产生的值执行测试时,可以理解.它通常可以通过合并两个分支并使用if..then..else本地来转换.

不便移除的一个示例如下(测试结合到解构):

match foo with
| (Baz x) when pred x -> ...
| _ -> ... 
Run Code Online (Sandbox Code Playgroud)


pad*_*pad 5

你需要when警惕:

let x = 2 in
let y = 5 in
match 2 with
| z when z = x -> "foo"
| z when z = y -> "bar"
| _ -> "baz";;
Run Code Online (Sandbox Code Playgroud)

错误消息非常有启发性.当你使用:

let x = 2 in
...
match 2 with
| x -> "foo"
| ...
Run Code Online (Sandbox Code Playgroud)

新值会x影响x上一个let-bound中的值,从而影响第一条错误消息.此外,由于新x的比赛的一切,两个图案下方y,并_有明显的冗余.

请注意,匹配常量(match 2 with)不是一个好主意.