如何处理嵌套的匹配表达式

时间:2019-01-12 03:10:54

标签: ocaml

我正在Ocaml中实现一种方法,以对随机类型'a的列表执行行程编码数据压缩。 列表中相同的连续元素将压缩为提供的代码开头定义的类型。我提供的代码无效。我认为这行不通的原因之一是,如果您查看第一个匹配项的大卡盘之间的新行,则新行之后的匹配项应属于较高匹配项。但是,Learn Ocaml中的编译器无法识别这一点。它将剩余的匹配语句(本来应该是第一个匹配项)自动分组到嵌套的match语句中。

这是Ocaml tutorial website(问题13)中的消费税之一: “直接实施所谓的行程编码数据压缩方法。即,没有明确创建包含重复项的子列表,如问题“将列表元素的连续重复项包装到子列表中”,而仅对其进行计数。如问题“修改的行程编码”,通过用X替换单例列表(1 X)来简化结果列表。”

type 'a rle =
  | One of 'a
  | Many of int * 'a;;

let encodeDirect (l: 'a list)=
  let rec helper current acc ll=
    match ll with
    |[] -> current::acc
    |[a]-> match current with
      |None -> (Some(One a))::acc 
      |Some(One q) -> (Some(Many(2,q)))::acc
      |Some(Many(t,y)) -> (Some(Many(t+1,y)))::acc 

      |a::(m::ls as e) -> if a=m then match current with 
      |None -> helper (Some(One a)) acc e
      |Some(One q) -> helper (Some(Many(2,q)))  acc e
      |Some(Many(t,y)) -> helper (Some(Many(t+1,y))) acc e
      else match current with 
        |None -> helper None (Some(One a)::acc) e
        |Some(One q) -> helper None (Some(Many(2,q))::acc)  e
        |Some(Many(t,y)) ->helper None (Some(Many(t+1,y))::acc) e
  in helper None [] l

以下是其工作方式的示例: 编码[“ a”;“ a”;“ a”;“ a”;“ b”;“ c”;“ c”;“ a”;“ a”;“ d”;“ e”;“ e”; “ e”;“ e”] ;; -:字符串列表= [许多(4,“ a”);一个“ b”;许多(2,“ c”);许多(2,“ a”);一个“ d”;  许多(4,“ e”)]

1 个答案:

答案 0 :(得分:0)

我经常在嵌套match时遇到相同的问题。您可以通过在内部匹配项中加上括号来解决该问题。

type 'a rle =
| One of 'a
| Many of int * 'a;;

let rec helper current acc ll=
  match ll with
  |[] -> current::acc
  |[a]->
    (match current with
    |None -> (Some(One a))::acc 
    |Some(One q) -> (Some(Many(2,q)))::acc
    |Some(Many(t,y)) -> (Some(Many(t+1,y)))::acc 
    )
  |a::(m::ls as e) ->
    if a=m then
      match current with 
      |None -> helper (Some(One a)) acc e
      |Some(One q) -> helper (Some(Many(2,q)))  acc e
      |Some(Many(t,y)) -> helper (Some(Many(t+1,y))) acc e
    else
      match current with 
      |None -> helper None (Some(One a)::acc) e
      |Some(One q) -> helper None (Some(Many(2,q))::acc)  e
      |Some(Many(t,y)) ->helper None (Some(Many(t+1,y))::acc) e