利用OCaml记录进行信息隐藏
给定 我如何实施利用OCaml记录进行信息隐藏,ocaml,record,records,Ocaml,Record,Records,给定 我如何实施 type 'a set = { insert : 'a -> 'a set; contains : 'a -> bool } ? 我试着关闭一些东西,比如一个列表,但是返回类型是错误的。。既然是这样。(忽略以下事实:此处的性能特征非常糟糕:-) 首先,它是布尔值,不是布尔值。:) 第二,这个定义相当繁琐。但你可以做一些类似的事情: let empty = let rec insert_f set a = match set with | []
type 'a set = { insert : 'a -> 'a set; contains : 'a -> bool }
?
我试着关闭一些东西,比如一个列表,但是返回类型是错误的。。既然是这样。(忽略以下事实:此处的性能特征非常糟糕:-)
首先,它是布尔值,不是布尔值。:) 第二,这个定义相当繁琐。但你可以做一些类似的事情:
let empty =
let rec insert_f set a =
match set with
| [] -> a :: []
| k :: rest ->
if k = a then
k :: rest
else
k :: insert_f rest a
in
let rec contains_f set a =
match set with
| [] -> false
| k :: rest ->
if k = key then
true
else contains_f rest a
in
{ insert = insert_f []; contains = contains_f []}
当然,使用非空集合的insert和contains实现来代替“assert false”
实现insert和contains的提示:不要使用任何列表,使用现有和新集合中函数的组合
你可以在W.Cook的“关于理解数据抽象,重温”一文中找到很好的例子,这篇文章可以在线获得。在这样的数据结构中,直接写空不是最容易的,因为你需要写插入,它将再次包含插入,因此。。。那么,让我们先写一段插页:
let empty = {
insert=(fun x -> {
insert=(fun x -> assert false);
contains=(fun x-> assert false)});
contains=(fun x -> false)}
在insert中,您希望递归调用insert,但第一个参数将是您正在编写的记录。下面是完整的解决方案:
let rec insert : 'a set -> 'a -> 'a set = fun s x -> {
insert = (fun y -> failwith "TODO");
contains = (fun y -> if x = y then true else s.contains y) }
insert
和contains
函数对于insert
案例来说似乎有点奇怪-insert
插入到一个空集将给出一个集合,当对插入值调用contains
时,返回true
否<代码>#(空。插入5)。包含5;;异常:Assert_failure(“//toplevel//”,8,29)。Yep,“Assert false”只是表示“这是未实现的”,并使程序无法清楚地指示它。当您实现它时,它确实应该创建一个新的集合。
let rec insert : 'a set -> 'a -> 'a set = fun s x -> {
insert = (fun y -> failwith "TODO");
contains = (fun y -> if x = y then true else s.contains y) }
let rec insert : 'a set -> 'a -> 'a set = fun s x ->
let rec ss = {
insert = ( fun y -> insert ss y);
contains = (fun y -> if x = y then true else s.contains y)}
in ss
let rec empty = {
insert = (fun x -> insert empty x);
contains = (fun x -> false)}