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 `false`

otherwise.

For example. the set of natural numbers is:

```
let nat x = x > 0
```

## contains

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
```

## empty

A set that contains nothing could never return `true`

.

```
let empty = fun _ -> false
```

## universal

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
```

## zip

A zip combines two sets with a combinator function.

```
let zip set1 set2 fn = fun v -> fn (set1 |> contains v) (set2 |> contains v)
```

## union

A set union combines the elements of both sets. We can express this with `zip`

:

```
let union set1 set2 = zip set1 set2 (||)
```

## intersect

An intersection of two sets only has members which belong in both the sets, or, ANDing.

```
let intersect set1 set2 = zip set1 set2 (&&)
```

## filter

```
let filter fn set1 = zip set1 fn (&&)
```

and moving on to constructing sets.

## singleton

A singleton set has only one element.

```
let singleton value = fun v -> value = v
```

## ofList

```
let ofList list = fun v -> list |> List.contains v
```

# Tests

```
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

Comments Disabled.