OCaml:检查引用是否已全部设置

OCaml:检查引用是否已全部设置,ocaml,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选项ref list->bo

我想编写一个函数,该函数提供一个选项引用列表,并检查每个引用是否为
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选项ref list->bool
类型

有什么办法可以让这一切顺利进行吗



我的实际情况是,我正在将许多命令行参数解析为一组引用,我从中提炼出上面的玩具示例。一些参数是字符串,一些是整数,等等。最初所有的引用都设置为
None
,当解析器找到一个命令行参数时,它将相应的引用设置为
Some…
。完成解析后,我发现自己想要迭代引用的子集,以确保它们不是仍然
None
,因为我希望相应的命令行参数是必需的。

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]
类型arg=
|取消
|整数的整数
|布尔的布尔
(*等*)
让我们核对一下=
List.for_all(fun r->(!r)Unset)rs
让我们=
检查[ref(Int 5);ref(布尔真);ref未设置]

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]
类型arg=
|取消
|整数的整数
|布尔的布尔
(*等*)
让我们核对一下=
List.for_all(fun r->(!r)Unset)rs
让我们=
检查[ref(Int 5);ref(布尔真);ref未设置]

解决问题的一种方法是,不能在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

一种解决问题的方法是,不能在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

'a option list
意味着list元素具有类型
'a option
,并且所有元素都应该具有您几乎肯定想要的类型
,而不是
=
@newacct为什么?@JohnWickerson:
=
是值相等的<代码>=和
=是物理相等。物理相等几乎从未被使用过,因为物理相等没有严格的文档记录,并且在不同类型之间有所不同(例如,
3==3
是真的,但
3.14==3.14
是假的),并且因为您通常从不关心两个事物在内存中是相同的结构还是具有相同值的不同结构,除非你处理的是可变结构,或者用内存做一些非常低级的事情。@newacct我明白了,谢谢。所以在我的特殊情况下,因为我想象None==None和None=None都成立,所以我可以使用其中一个。但总的来说,我将试着记住使用而不是!=。再次感谢。
'a option list
意味着list元素具有类型
'a option
,并且所有元素都应该具有您几乎肯定想要的类型
,而不是
=
@newacct为什么?@JohnWickerson:
=
是值相等的<代码>=
=是物理相等。物理相等几乎从未被使用过,因为物理相等没有严格的文档记录,并且在不同类型之间有所不同(例如,
3==3
是真的,但
3.14==3.14
是假的),并且因为您通常从不关心两个事物在内存中是相同的结构还是具有相同值的不同结构,除非你处理的是可变结构,或者用内存做一些非常低级的事情。@newacct我明白了,谢谢。所以在我的特殊情况下,因为我想象None==None和None=None都成立,所以我可以使用其中一个。但总的来说,我将试着记住使用而不是!=。再次感谢。