I have below a description of a data structure I need and I want to implement it using immutable data structures. I\'m trying to determine... is there an existing data struc
Thanks to Juliet's kind information, I have implemented what I need and I put it here in case anyone else might find it useful.
let rec removeLast (s : Set<'a>, num : int) : Set<'a> =
match num with
| 0 -> s
| _ -> removeLast(s.Remove(s.MinimumElement), num-1)
type History<'a when 'a : comparison>(underlying : Set<'a>, removal : History<'a> -> int) =
member this.Add(x) =
History(removeLast(underlying, removal(this)).Add x, removal)
member this.Count = underlying.Count
member this.Min = underlying.MinimumElement
member this.Max = underlying.MaximumElement
member this.Under = underlying
let maxHist = 2
let maxCountRemover (h : History<int>) =
if h.Count >= maxHist
then h.Count - maxHist + 1
else 0
let testHistory =
let s = History(Set.empty, r)
let s = s.Add(1);
printfn "%i: %i - %i" s.Count s.Min s.Max
let s = s.Add(2);
printfn "%i: %i - %i" s.Count s.Min s.Max
let s = s.Add(3);
printfn "%i: %i - %i" s.Count s.Min s.Max
let s = s.Add(4);
printfn "%i: %i - %i" s.Count s.Min s.Max
let s = s.Add(5);
printfn "%i: %i - %i" s.Count s.Min s.Max
printfn "%A" s.Under
Without knowing more about your requirements, I'd just say a vanilla Set<'a>
does a more than adequate job. I'd prefer a 'Set' over a 'List' so you always have O(lg n) access to the largest and smallest items, allowing you to ordered your set by insert date/time for efficient access to the newest and oldest items.
Seems very easy to wrap up a set so that its Add/Remove methods invoke your callbacks:
type AwesomeSet(internalSet : Set<'a>, insertCallback : 'a -> unit, removeCallback : 'a -> unit) =
member this.Add(x) =
insertCallback(x)
AwesomeSet(internalSet.Add x, insertCallback, removeCallback)
member this.Remove(x) =
removeCallback(x)
AwesomeSet(internalSet.Remove x, insertCallback, removeCallback)
member this.Count = internalSet.Count
member this.Min = internalSet.MinimumElement
member this.Max = internalSet.MaximumElement