假设我有[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个元素列表。我可以采取一种方法来匹配这样的事情吗?我应该使用嵌套模式匹配吗?
答案 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 *)