2014-10-01 39 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