# `Feel.Type.Witness`
[🔗](https://github.com/FeeJai/BDM/blob/feel-v0.1.0/apps/feel/lib/feel/type/witness.ex#L1)

A value of a type: the proof that a type is not empty, and the counterexample that a question about types needs.

`of/1` returns a value that `Feel.Type.Union.contains?/2` says is in the union, or `:none`. Every value it returns has been
checked, so it is a witness whatever the type was made of: a type that was widened by a limit, or made by an operation that
gives more than it has to, cannot make `of/1` return a value that is not in it. `:none` is not a proof that the type is empty;
it is that no value was found. A time, a date and time, a range and a function are not made (a type that has only those has
no witness), and a union has one as soon as one of its members does. A range is made from two values of its endpoint type.

`find/2` is the same with a condition on the value, for a question that is about two types (a value in one and not in the
other).

The values are those of the host (`Feel.Value`): a `Decimal`, a binary, a boolean, `nil`, a list, a plain map for a context, a
date, and the two durations.

    iex> Feel.Type.Witness.of([:null])
    {:ok, nil}
    iex> {:ok, number} = Feel.Type.Witness.of([{:number, Feel.Type.NumberSet.interval({Decimal.new(2), :open}, Decimal.new(4))}])
    iex> Decimal.compare(number, 2) == :gt and Decimal.compare(number, 4) != :gt
    true
    iex> Feel.Type.Witness.of([{:except, {:list, [:any, :null]}, [{:list, [:number, :null]}]}])
    {:ok, [true]}

# `edges`

```elixir
@spec edges(Feel.Type.Union.t(), pos_integer()) :: [term()]
```

Values of the union at which an operation is most likely to fail (D-161): zero and the smallest numbers there are, the
ends of the sets, the largest number, one, a half and two; the first and the last day of the calendar; for a string, the
empty one, one character, a bracket and a dollar alone, and some with several characters or of more than one byte. Each
has been checked to be in the union, and there are at most `limit` of them.

    iex> set = Feel.Type.NumberSet.interval(Decimal.new(0), Decimal.new(150))
    iex> Feel.Type.Witness.edges([{:number, set}], 5) |> Enum.map(&Decimal.to_string/1)
    ["0", "1E-6176", "150", "1", "2"]

# `find`

```elixir
@spec find(Feel.Type.Union.t(), (term() -&gt; boolean())) :: {:ok, term()} | :none
```

A value of the union for which `accept` is true, or `:none`.

# `of`

```elixir
@spec of(Feel.Type.Union.t()) :: {:ok, term()} | :none
```

A value of the union, or `:none`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
