利用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)}