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]}
Summary
Functions
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.
A value of the union for which accept is true, or :none.
A value of the union, or :none.
Functions
@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"]
@spec find(Feel.Type.Union.t(), (term() -> boolean())) :: {:ok, term()} | :none
A value of the union for which accept is true, or :none.
@spec of(Feel.Type.Union.t()) :: {:ok, term()} | :none
A value of the union, or :none.