匹配变量(或以其他方式引入匹配逻辑的抽象)

ᆼᆺᆼ*_*ᆼᆺᆼ 1 ocaml ml pattern-matching

可以匹配文字(显然):

let res = match x with 
  | "abc" -> 1
  | "def" as x -> something_else x
Run Code Online (Sandbox Code Playgroud)

:但是,是否可以匹配变量的值,因此在整个代码中不会重复文字?

let abc = "abc"
let def = "def"
let res = match x with
  | (abc) -> 1
  ...
Run Code Online (Sandbox Code Playgroud)

(以上当然不符合abc,但在每种情况下都会匹配)

F#中,可以使用活动模式:

let (|IsAbc|IsDef|) str = if str = abc then IsAbc(str)
                     else if str = def then IsDef(str)
                     ...
let res = match x with 
          | IsAbc x -> 1
          | IsDef x -> somethingElse x
Run Code Online (Sandbox Code Playgroud)

这允许抽象匹配逻辑并仅定义文字一次.我怎么能在OCaml中实现这个目标?

我得到的最接近的是:感觉有点笨拙?

let is_abc str = str = abc 
let is_def str = str = def
...
let res = match x with
  | x when is_abc x -> 1
  | x when is_def x -> something_else x
Run Code Online (Sandbox Code Playgroud)

或使用if:它看起来不如优雅match(同样,匹配y,必须进行n次编辑,与使用时相比为1 match)

let res = if x = abc then 1
     else if x = def then something_else x
Run Code Online (Sandbox Code Playgroud)

Jef*_*eld 6

使用when本质上是您在OCaml中可以做的最好的.我不认为它看起来比你提供的F#等同更笨拙.但这也许是品味问题.

您也可以分解并使用if表达式.这就是我个人所做的.我认为假装OCaml match比实际更普遍没有任何优势.

你可能会认为它是一个类似的折衷ifswitch在C的语言.如果要与编译时已知的一组值进行比较,switch则效率会更高.但它并不试图成为一个普遍的if.