OCaml:List.iter 从匹配后的下一个元素开始
OCaml: List.iter starts with next element after match
我发现了一件奇怪的事:
在我的代码中,我想输出一个包含特殊类型元素的列表的数据,该元素由另一种类型和 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 移到顶部,因为我需要右括号
我做错了什么,我错过了什么错误吗?有谁知道如何输出我的数据?
在 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
表达式来表示整数上的那种 "pattern-matching"。
缩进代码的标准方法是:
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;
我发现了一件奇怪的事:
在我的代码中,我想输出一个包含特殊类型元素的列表的数据,该元素由另一种类型和 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 移到顶部,因为我需要右括号
我做错了什么,我错过了什么错误吗?有谁知道如何输出我的数据?
在 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
表达式来表示整数上的那种 "pattern-matching"。
缩进代码的标准方法是:
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;