信息隐藏与OCaml记录

时间:2015-10-13 18:36:38

标签: ocaml record records

鉴于

type 'a set = { insert : 'a -> 'a set; contains : 'a -> bool }

如何实施

val empty : 'a set

我试过关闭某些东西,说一个列表,但返回类型是错误的..因为它是。 (忽略这里的表现特征非常糟糕:-))

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 []}

2 个答案:

答案 0 :(得分:3)

在这样的数据结构中直接写空并不是最简单的,因为你需要编写插入,这将再次包含一个插入,所以一个...所以让我们先写插入:

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,但第一个参数将是您正在编写的记录。所以这是完整的解决方案:

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

答案 1 :(得分:0)

首先,它是布尔,而不是布尔。 :)

其次,这个定义非常麻烦。但你可以这样做:

let empty = {
  insert=(fun x -> {
           insert=(fun x -> assert false);
           contains=(fun x-> assert false)});
  contains=(fun x -> false)}

使用insert的实现并包含非空集代替“断言错误”当然。

实现insert和contains的提示:不要使用任何列表,使用现有和新集合中的函数组合。

你可以找到很好的例子,例如W. Cook的“关于理解数据抽象,再访”,该论文可在线获取。