2017-08-12 73 views
3

有没有一种方法来模式匹配独立于构造函数arity的构造函数?有时在模式匹配中,我只关心构造函数而不关心与之相关的数据。Ocaml模式匹配数据构造函数独立于其构造

我担心的是,当我在ADT中更改构造函数的构造函数时,我必须通过并更改所有模式匹配,即使丢弃所有“字段”(什么是正确的术语?)数据构造函数。

假设我有多个构造

(* time * message *) 
type log_message = 
    Warning of float * string 
    | Error of float * string 

的ADT,我要检查这种类型的值,而是只关心构造我写类似

let is_error_message x = match x with 
    | Warning _, _ -> false 
    | Error _, _ -> true 

如果后来我想回去添加严重性字段来警告,给我

type log_message = 
    Warning of float * string * int 
| Error of float * string 

我必须在is_error_message的模式中添加一个新的通配符来满足类型检查器。

let is_error_message x = match x with 
    | Warning _, _, _ -> false 
    | Error _, _ -> true 

回答

4

类型定义

type log_message = 
    | Warning of float * string 
    | Error of float * string 

意味着两个构造函数(WarningError)不接受两个参数,但其中的一个,而产物(即元组)。所以,你instatiate如下:

Warning (4.0, "you better be warned") 

当这种变异的一个实例进行模式匹配,你可以只使用_指定任意长度的元组(如果你不关心传递给构造函数的参数):

type log_message = 
    | Warning of float * string 
    | Error of float * string;; 

let is_error_message x = match x with 
    | Warning _ -> false 
    | Error _ -> true;; 

is_error_message (Warning (2.0, "totally not an error"));; 
- : bool = false 
+0

我想我的意思是说'(*浮动字符串)'&C ...用于多参数的构造函数,而不是一元的构造函数警告服用我搞砸语法的元组... (然后不知道为什么'Warning _ _'无效)。你所说的完全正确,但我不想只是静静地解决这个问题。 –

+1

这是不正确的,正则构造函数的参数不是元组。 '_'可以匹配多个参数的原因是因为它已被添加为一个功能来覆盖此用例。 – gsg

+0

@gsg哪个版本加入了? –