OCaml:List.iter以匹配后的下一个元素开始

时间:2016-06-02 07:32:42

标签: list functional-programming ocaml

我发现了一件奇怪的事情:

在我的代码中,我想输出包含特殊类型元素的列表数据,该列表由另一种类型和name组成。

我之前从未需要这样的代码,所以我不知道为什么它不起作用或被禁止或类似的东西。

List.iter(
    fun x -> (
        fprintf oc "(";
        fprintf oc "asdf";
        match x.kind with
        |Id -> fprintf oc "Id"
        |Op -> fprintf oc "Op"
        |Test -> fprintf oc "Test"
        ;  
        fprintf oc "fdsa";
        fprintf oc "%s" x.name;
        fprintf oc "),";
    )   
)list;

asdf和fdsa是测试输出,以查看问题所在。 oc是我的输出通道,用于写入文件,其余应该是安静的自我解释为Ocaml-Pros像你一样:)

不幸的是,我只得到这样的结果: (asdfId(asdfOp(asdfId似乎在匹配后停止执行,并继续列表的下一个元素。

预期输出为(asdfIdfdsatest1),(asdfOpfdsatest2) ...

我不能将x.name移到顶部,因为我需要结束括号

我做错了什么,我错过了什么错误?有谁知道如何输出我的数据?

2 个答案:

答案 0 :(得分:7)

在OCaml match的优先级高于;。因此,您需要将match包装在一对括号中。

让我们在顶层尝试以下内容:

> match 0 with
   | 0 -> print_string "zero "
   | _ -> print_string "non-zero";
  print_endline "42";;

Output: zero 

现在让我们在match表达式周围添加括号:

> (match 0 with
   | 0 -> print_string "zero "
   | _ -> print_string "non-zero");
  print_endline "42";;

Output: zero 42

旁注:在现实生活中,最好将if表达式用于整数上的那种“模式匹配”。

答案 1 :(得分:1)

缩进代码的标准方法是:

List.iter (fun x ->
    fprintf oc "(";
    fprintf oc "asdf";
    match x.kind with
    |Id -> fprintf oc "Id"
    |Op -> fprintf oc "Op"
    |Test -> fprintf oc "Test"
        ;
        fprintf oc "fdsa";
        fprintf oc "%s" x.name;
        fprintf oc "),";
  ) list;

在这里你可以看到最后3个语句只在第3个分支中执行。

要解决这个问题,你可以用这种方式重写你的代码(第一种方式是通常的方式,从我所看到的:

List.iter (fun x ->
    fprintf oc "(";
    fprintf oc "asdf";
    begin match x.kind with
    |Id -> fprintf oc "Id"
    |Op -> fprintf oc "Op"
    |Test -> fprintf oc "Test"
    end;
    fprintf oc "fdsa";
    fprintf oc "%s" x.name;
    fprintf oc "),";
  ) list;

List.iter (fun x ->
    fprintf oc "(";
    fprintf oc "asdf";
    (match x.kind with
     |Id -> fprintf oc "Id"
     |Op -> fprintf oc "Op"
     |Test -> fprintf oc "Test");
    fprintf oc "fdsa";
    fprintf oc "%s" x.name;
    fprintf oc "),";
  ) list;