(* Assumption: Set elements are unique, so no two elements in a single
 *             set have the same value. *)

type 'a set = Set of 'a list

(* Create an empty set *)
let emptySet = Set([])

(* Delete an element from a set (if it does not exists in it yet)
 * and return the new set with the element *)
let addElem elem set = match set with
      Set ([]) -> Set([elem])
    | Set (l) -> if List.mem elem l then set else Set(elem::l)

(* Delete an element from a set (if it exists in it) and return
 * the new set without the element *)
let delElem elem set =
    let rec delFromList elem = function
          [] -> []
        | h::t -> if h = elem then t else h::(delFromList elem t)
    in match set with
      Set ([]) -> set
    | Set (l) -> Set(delFromList elem l)

(* Check if an element exists in a set *)
let isElem elem = function Set (l) -> List.mem elem l

(* Get the union of sets a and b as a new set *)
let union a b =
    match a with
      Set ([]) -> b
    | Set(la) -> match b with
          Set ([]) -> a
        | Set(lb) ->
            Set(la @ List.filter (fun e -> not (List.mem e la)) lb)

(* Get the intersection of sets a and b as a new set *)
let intersection a b =
    match a with
      Set ([]) -> a
    | Set(la) -> match b with
          Set ([]) -> b
        | Set(lb) -> 
            let b_in_a = List.filter (fun e -> List.mem e la) lb in
            Set(List.filter (fun e -> List.mem e lb) b_in_a)

(* Some tests *)
let a = emptySet;;
let a = addElem 2 a;;
let a = addElem 8 a;;
let a = addElem 3 a;;
let a = addElem 7 a;;
let a = addElem 1 a;; (* 2, 8, 3, 7, 1 *)

isElem 7 a;; (* true *)
isElem 5 a;; (* false *)

let b = delElem 5 a;;

let b = delElem 1 a;;
let b = delElem 7 b;;
let b = addElem 9 b;;
let b = addElem 0 b;; (* 0, 9, 3, 8, 2 *)

union a b;; (* 1, 7, 3, 8, 2, 0, 9 *)
intersection a b;; (* 3, 8, 2 *)