【问题标题】:OCaml pattern match arbitrarily many list elementsOCaml 模式匹配任意多个列表元素
【发布时间】:2017-01-17 20:31:53
【问题描述】:

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

【问题讨论】:

    标签: list pattern-matching ocaml


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      如果您只是检查列表的第一个和最后一个元素,您可能希望使用条件语句而不是模式匹配:

      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 *)
      

      但是,如果您尝试提取中间模式,则可能值得使用模式匹配。由于他指出的原因(模式匹配无法匹配列表的末尾),我们可以做类似于 Jeffery 建议的事情:

      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 *)
      

      【讨论】:

        猜你喜欢
        • 2011-06-14
        • 1970-01-01
        • 1970-01-01
        • 2014-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-30
        相关资源
        最近更新 更多