Skip to content

Instantly share code, notes, and snippets.

@BashkaMen
Last active February 3, 2022 10:39
Show Gist options
  • Save BashkaMen/de8849141e5412f307a82bfe69debdf8 to your computer and use it in GitHub Desktop.
Save BashkaMen/de8849141e5412f307a82bfe69debdf8 to your computer and use it in GitHub Desktop.
open System.Collections.Generic
type xSet<'Id, 'T when 'Id : comparison and 'T : equality>(itemId, source: Map<'Id, 'T>) =
let mkNew source = xSet(itemId, source)
member val private HashCode = hash source
override this.GetHashCode() = this.HashCode
override this.Equals other =
match other with
| :? xSet<'Id, 'T> as other -> other.HashCode = this.HashCode
| _ -> false
interface IEnumerable<'T> with
member this.GetEnumerator(): IEnumerator<'T> =
source
|> Map.toSeq
|> Seq.map snd
|> fun x -> x.GetEnumerator()
member this.GetEnumerator() = (this :> IEnumerable<'T>).GetEnumerator() :> System.Collections.IEnumerator
member this.IsEmpty = source.IsEmpty
member this.Add(item) =
source
|> Map.add (itemId item) item
|> mkNew
member this.Remove(item) = Map.remove (itemId item) source
member this.Contains item = Map.containsKey (itemId item)
member this.Filter predicate = source |> Map.filter predicate |> mkNew
module xSet =
let create itemId source = xSet(itemId, source)
let empty itemId = xSet(itemId, Map.empty)
let ofSeq itemId xs =
xs
|> Seq.map ^ fun x -> (itemId x, x)
|> Map.ofSeq
|> create itemId
let toSeq (set: xSet<_, _>) = set :> IEnumerable<_>
let add x (set: xSet<_, _>) = set.Add(x)
let addMany xs (set: xSet<_, _>) = Seq.fold (fun state x -> add x state) set xs
let remove x (set: xSet<_, _>) = set.Remove(x)
let filter predicate (set: xSet<_, _>) = set.Filter predicate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment