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

时间:2017-12-12 21:58:45

标签: pattern-matching ocaml ml

可以匹配文字(显然):

let res = match x with 
  | "abc" -> 1
  | "def" as x -> something_else x

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

let abc = "abc"
let def = "def"
let res = match x with
  | (abc) -> 1
  ...

(上述内容当然不会与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

这允许抽象匹配逻辑并仅定义文字一次。我怎样才能在 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

或者使用if但是它看起来不如match优雅(同样,要匹配y n 编辑必须要做,与使用match)时的1相比

let res = if x = abc then 1
     else if x = def then something_else x

3 个答案:

答案 0 :(得分:6)

使用when基本上是您在OCaml中可以做的最好的事情。我认为它看起来比你提供的F#等同物更笨拙。但这或许是一个品味问题。

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

您可能会认为它与C语言中的ifswitch类似。如果要与编译时已知的一组值进行比较,switch效率会更高。但它并没有尝试成为一般化的if

答案 1 :(得分:3)

您可以使用C-style preprocessor

IdSSLOpenSSL

答案 2 :(得分:1)

模式匹配会带来穷举,如果你使用变量,那么你就更容易处理一个简单的if表达式。 您可以尝试使用匹配来获得优雅的语法,并针对大量可能的值进行测试,例如:

match x with 
| value A -> function A
| value B -> function B
| ...
| value N -> function N

如果遇到这种情况,可以使用结构将值映射到相应的函数。

匹配语法非常优雅,很容易尝试在任何情况下使用它,但目的对于保持语言的简单性非常重要。