adelbertc
adelbertc

Reputation: 7320

Information hiding with OCaml records

Given

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

How can I implement

val empty : 'a set

?

I've tried closing over something, say a list, but the return type is wrong.. since it is. (ignoring the fact that the performance characteristics here are terrible :-) )

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

Upvotes: 1

Views: 177

Answers (2)

lavi
lavi

Reputation: 237

directly writing the empty is not the easiest in such data structure, as you will need to write the insert, which will contains again an insert and so one... So let's write first the 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) }

in insert, you want to recursively call insert, but the first parameter will be the record you are writing. So here is the complete solution:

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

Upvotes: 3

dmbaturin
dmbaturin

Reputation: 91

First of all, it's bool, not boolean. :)

Second, this definition is quite cumbersome. But you can do something like:

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

with your implementations of insert and contains for non-empty sets in place of "assert false" of course.

A hint for implementing insert and contains: don't use any lists, use compositions of a functions from existing and new sets.

You can find nice examples in e.g. "On Understanding Data Abstraction, Revisited" by W. Cook, that paper is available online.

Upvotes: 0

Related Questions