2014-10-01 34 views
0

我想写一个函数给出一个选项参考列表,并检查每个参考不是None。也就是说,我想要一个功能OCaml:检查参考全部设置

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类型。

有什么办法可以使这项工作?


我的实际情况,从我上面的蒸馏玩具例子,是我解析了一些命令行参数成一束引用。一些参数是字符串,一些是整数等等。最初,所有参考都设置为None,并且当解析器找到命令行参数时,它将相应的参考设置为Some ...。完成解析之后,我发现自己希望迭代一部分引用以确保它们不是仍然是None,因为我希望相应的命令行参数是必需的。

+2

''一个选项列表'意味着列表元素具有类型''选项',并且所有元素应该具有相同的类型 – ivg 2014-10-01 16:37:28

+0

您几乎可以肯定''''而不是'!=' – newacct 2014-10-01 19:03:11

+0

@newacct为什么? – 2014-10-01 20:57:23

回答

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

一种方法是,你的参数列表不能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