F#不可变大小的窗口数据结构

时间:2010-08-04 16:46:19

标签: data-structures f# immutability

我在下面描述了我需要的数据结构,并且我想使用不可变数据结构来实现它。我试图确定......是否存在一个现有的数据结构,它将支持我在这里尝试做的事情,或者我需要创建一个 - 如果我需要创建它,那将是一件好事开始的地方(积木)?


我有一个稳定的特定类型的传入值流。我想将它们添加到持久/不可变数据结构中以保存它们的历史记录,并且在每次添加时,它将检查历史记录并确定是否将删除一个或多个最旧的项目(例如,如果历史记录是>某个长度或某个值具有某种特性。)

2 个答案:

答案 0 :(得分:3)

在不了解您的要求的情况下,我只想说一个香草Set<'a>做得不够好。我更喜欢在'List'上设置'Set',这样你就可以对最大和最小的项目进行O(lg n)访问,允许你按插入日期/时间订购你的设置,以便有效地访问最新和最旧的项目

似乎很容易包装一个集合,以便其添加/删除方法调用你的回调:

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

答案 1 :(得分:1)

感谢朱丽叶的亲切信息,我已经实现了我需要的东西,我把它放在这里,万一其他人可能会发现它有用。

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