OCaml:检查引用都已设置

时间:2014-10-01 16:18:18

标签: ocaml

我想编写一个给出选项引用列表的函数,并检查每个引用是否为None。也就是说,我想要一个功能

let check rs =
  List.for_all (fun r -> (!r) != None) rs

let _ =
  check [ref (Some 5); ref (Some true)]

这不起作用。编译器找不到列表[ref (Some 5); ref (Some true)]的类型,即使check函数看起来本质上没问题,但它具有很好的多态'a option ref list -> bool类型。

有没有办法让这项工作?


我从上面提炼出玩具示例的真实情况是,我正在将一些命令行参数解析为一堆引用。一些参数是字符串,一些是int,等等。最初所有引用都设置为None,当解析器找到命令行参数时,它会设置对Some ...的相应引用。完成解析之后,我发现自己想要遍历引用的子集以确保它们不是None,因为我希望相应的命令行参数是必需的。

2 个答案:

答案 0 :(得分:3)

OCaml不支持异构容器。您可以尝试解决这个问题:

type arg =
  | Unset
  | Int of int
  | Bool of bool
  (* etc *)

let check rs =
  List.for_all (fun r -> (!r) <> Unset) rs

let _ =
  check [ref (Int 5); ref (Bool true); ref Unset]

答案 1 :(得分:1)

查看问题的一种方法是,您的参数列表无法在OCaml中获得类型:

# [ ref (Some 5); ref (Some true) ];;
Error: This expression has type bool option ref
       but an expression was expected of type int option ref
       Type bool is not compatible with type int 

如果您愿意将引用包装在对象界面中,则可以使用以下列表:

# class cr x = object method is_set = !x <> None end;;
class cr : 'a option ref -> object method is_set : bool end
# let reflist = [ new cr (ref (Some 5)); new cr (ref (Some true))];;
val reflist : cr list = [<obj>; <obj>]

然后你可以检查列表中的所有元素:

# List.for_all (fun x -> x#is_set) reflist;;
- : bool = true