我有以下代码,我打算使用自定义类型Map
和variable
创建location
。我知道应该订购密钥类型(一些比较器功能)。我该如何添加这些规则才能使其工作?另外,我发现这里的代码很难看。我真的需要;;
和type
末尾的module
吗?
type variable = string;;
type location = int;;
module LocationMap = Map.Make(variable);;
module EnvironmentMap = Map.Make(location);;
修改 这是我的其余代码:
type variable = Variable of string
type location = Location of int
module LocationMap = Map.Make(struct type t = variable let compare = compare end)
module EnvironmentMap = Map.Make(struct type t = variable let compare = compare end)
(*file read function*)
let read_file filename =
let lines = ref [] in
let chan = open_in filename in
try
while true do
lines := input_line chan :: !lines
done;
!lines
with End_of_file ->
close_in chan;
List.rev !lines
in
(*get the inputs*)
let inputs = read_file Sys.argv.(1) in
for i = 0 to List.length inputs - 1 do
Printf.printf "%s\n" (List.nth inputs i)
done;
这有语法错误。我不知道为什么。
的 EDIT2
我通过以下编辑来完成这项工作:
type variable = Variable of string
type location = Location of int
module LocationMap = Map.Make(struct type t = variable let compare = compare end)
module EnvironmentMap = Map.Make(struct type t = variable let compare = compare end)
(*file read function*)
let read_file filename =
let lines = ref [] in
let chan = open_in filename in
try
while true do
lines := input_line chan :: !lines
done;
!lines
with End_of_file ->
close_in chan;
List.rev !lines
(*get the inputs*)
let () =
let inputs = read_file Sys.argv.(1) in
for i = 0 to List.length inputs - 1 do
Printf.printf "%s\n" (List.nth inputs i)
done;
对于很长的问题列表感到抱歉,let () =
在这做什么?当我使用let
定义函数时,我不需要in
吗?
答案 0 :(得分:2)
应用Map.Make仿函数时,需要提供包含类型和比较函数的结构:
module LocationMap =
Map.Make(struct type t = variable let compare = compare end)
module EnvironmentMap =
Map.Make(struct type t = location let compare = compare end)
您永远不需要在编译代码中使用;;
。只有在使用顶层时才需要它,告诉它何时应该评估你到目前为止输入的内容。
有些人在编译的代码中使用;;
,但你永远不需要这样做,我个人从不这样做。总有一种方法可以在不使用;;
的情况下获得相同的效果。
<强>更新强>
let compare = compare
将预先存在的OCaml函数compare
(臭名昭着的多态比较函数)绑定到结构内的名称compare
。因此,它创建了一个使用多态比较进行比较的Map。这通常是你想要的。
我创建了一个包含您的定义的文件(没有;;
)和上面的代码,然后使用ocamlc -c
进行编译。没有语法错误。我很肯定你不需要使用;;
,因为我已经写了很多行代码而没有它。
请注意,我不说如果从语法正确的OCaml代码中删除;;
,结果总是在语法上正确。有一些习惯用法仅在您使用;;
时才有效。我个人只是避免那些习语。
更新2
模块顶层的let
是特殊的,没有in
。它定义了模块的全局值。 OCaml将每个源文件视为一个模块(免费,我喜欢说),其名称与源文件名相同(大写)。
您实际上可以在let pattern = expression
中拥有任何模式。所以let () = ...
完全正常。它只是说表达式有单位类型(因此模式匹配)。