What would a defintion of classic sets in F# look like. These would just be composed of functions, without any underlying data types.
The simplesy defintion of a
Set is a boundary - everything inside it belongs to the set, everything outside it does not. We can define that membership using a simple function type.
type 'a Set = 'a -> bool
true for a value that belongs to the set and
For example. the set of natural numbers is:
let nat x = x > 0
Contains just calls our function, but constrains its value to
bool- which will help out type inference down the line.
let contains value set : bool = set value
A set that contains nothing could never return
let empty = fun _ -> false
A universal set is a set which contains all objects, including itself. For now, our definition does not care about Russel’s paradox.
let universal = fun _ -> true
A zip combines two sets with a combinator function.
let zip set1 set2 fn = fun v -> fn (set1 |> contains v) (set2 |> contains v)
A set union combines the elements of both sets. We can express this with
let union set1 set2 = zip set1 set2 (||)
An intersection of two sets only has members which belong in both the sets, or, ANDing.
let intersect set1 set2 = zip set1 set2 (&&)
let filter fn set1 = zip set1 fn (&&)
and moving on to constructing sets.
A singleton set has only one element.
let singleton value = fun v -> value = v
let ofList list = fun v -> list |> List.contains v
assert (1 |> FSet.singleton |> FSet.contains 1) assert (1 |> FSet.singleton |> FSet.contains 0 |> not) assert ([1; 2; 3] |> FSet.ofList |> FSet.contains 1) assert ([1; 2; 3] |> FSet.ofList |> FSet.union (FSet.singleton 4) |> FSet.contains 4) assert ([1; 2; 3] |> FSet.ofList |> FSet.intersect (FSet.singleton 1) |> FSet.contains 1) assert ([1; 2; 3] |> FSet.ofList |> FSet.intersect (FSet.singleton 4) |> FSet.contains 4 |> not)
Last modified on 2019-01-31