Feel.Type.Witness (feel v0.1.0)

Copy Markdown View Source

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

edges(union, limit \\ 24)

@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(union, accept)

@spec find(Feel.Type.Union.t(), (term() -> boolean())) :: {:ok, term()} | :none

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

of(union)

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

A value of the union, or :none.