OCaml模式匹配任意多个列表元素

时间:2017-01-17 20:31:54

标签: list pattern-matching ocaml

假设我有[1;2;3;4;5;6;9][1;2;3;9]等列表,我想编写一个模式,用于捕获以1开头并以9结尾的列表,并捕获列表中间的值。这可能与OCaml的模式匹配有关吗?

我试图写一些像

这样的东西
match l with
| 1::middle::9

match l with
| 1::middle::9::[]

但我不确定这些是在做我想要的,而且可能只是匹配3个元素列表。我可以采取一种方法来匹配这样的事情吗?我应该使用嵌套模式匹配吗?

2 个答案:

答案 0 :(得分:3)

没有匹配列表末尾的模式,所以没有像你想要的模式。你可以做两场比赛:

match l with
| 1 :: _ -> (
    match List.rev l with
    | 9 :: _ -> true
    | _ -> false
)
| _ -> false

查找列表的结尾是线性时间操作。如果您的列表可能很长,则可能需要使用不同的数据结构。

答案 1 :(得分:0)

如果你只是对列表的第一个和最后一个元素进行检查,你可能想要使用条件语句而不是模式匹配:

let is_valid l = 
    let open List in
    let hd' = hd l in (* Get the first element of the list *)
    let tl' = rev l |> hd in (* Get the last element of the list *)
    if hd' = 1 && tl' = 9 then true else false

    is_valid [1;2;3;4;5;6;9] (* bool = true *)

但是,如果您尝试提取中间模式,则可能值得使用模式匹配。我们可以做类似杰弗瑞建议的事情,因为他指出的原因(模式匹配不能匹配列表的结尾):

let is_valid l =
    let open List in
    match l with
    | 1 :: mid ->  (* `mid` holds list without the `1` *)
        (match rev mid with (* `rev_mid` holds list without the 9 but reversed *)
        | 9 :: rev_mid -> Some (rev rev_mid) (* reverse to get correct order *)
        | _ -> None)
    | _ -> None


    is_valid [1;2;3;4;5;6;9] (* int list option = Some [2; 3; 4; 5; 6] *)

然后使用此函数,您可以使用简单的模式匹配来查找有效列表的中间位置:

match is_valid l with
| Some middle -> middle (* the middle of the list *)
| None -> [] (* nothing — list was invalid *)