我发现了一件奇怪的事情:
在我的代码中,我想输出包含特殊类型元素的列表数据,该列表由另一种类型和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移到顶部,因为我需要结束括号
我做错了什么,我错过了什么错误?有谁知道如何输出我的数据?
答案 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;