(* modul similar cu Set, parametrizat cu un modul pentru elemente *)
(* ExtraSet are toate funcțiile din Set, plus încă una pentru permutări *)

module ExtraSet(Elt: Set.OrderedType) = struct
  module S = Set.Make(Elt)
  module EltList = struct     
    type t = Elt.t list        (* listă cu tipul de elemente din Elt *)
    let compare = compare
  end
  module LS = Set.Make(EltList)        (* pentru mulțimi de liste de Elt.t *)
  include S  (* putem folosi funcțiile din S fără prefixul S. *)


  let rec perm mult =  (* funcția cerută *)
    (* addhd: funcția din fold are 2 argumente: lista la care adaugă h,
     * și mulțimea de liste la care adaugă rezultatul
     * LS.fold are doar funcția, deci mai ia 2 parametri:
     * mulțimea de parcurs și valoarea inițială, o mulțime de liste *)
    let addhd h = LS.fold (fun lst -> LS.add (h :: lst)) in

    if S.is_empty mult then LS.singleton []  (* 0! = 1, permutarea vidă *)
    (* fold parcurge m și aplică acumulatorului (mulțime de liste) funcția:
     * scoate el din m, fă permutările, pune el în fața fiecăreia, adaugă-le *)
    else S.fold (fun e -> S.remove e mult |> perm |> addhd e) mult LS.empty
end
                                         
module Int = struct
  type t = int
  let compare = compare
end
module IP = ExtraSet(Int)
module SP = ExtraSet(String)
                   
let s123 = IP.(empty |> add 1 |> add 2 |> add 3)
let sabc = SP.(empty |> add "a" |> add "b" |> add "c")
let perm_i = IP.(perm s123 |> LS.elements)
let perm_s = SP.(perm sabc |> LS.elements)

This document was generated using caml2html