A literal the server sent, back into an Elixir term.
Public because latu_ml reads it: an ML attribute — a coefficient, an intercept, a vector —
comes back from the server as a literal, not as a frame. Latu.Plan.lit/1 is the other
direction, and the two are deliberately not symmetric: the encoder picks one Spark type per
Elixir type, while this has to read back every arm Spark can produce.
Transcribed from PySpark's LiteralExpression._to_value, with three departures recorded in
docs/deviations.md: Latu decodes specialized_array, which PySpark refuses; Latu reads the
data_type field in preference to the struct_type field 4.1 deprecated, which PySpark still
reads exclusively; and a UDT comes back as a Latu.Result.UDT where PySpark raises.
Summary
Functions
The Elixir term a literal carries, or {:error, _} naming the arm that has no term.
Functions
@spec value(Latu.Protocol.Spark.Connect.Expression.Literal.t() | nil) :: {:ok, term()} | {:error, Latu.Error.t()}
The Elixir term a literal carries, or {:error, _} naming the arm that has no term.
Integers come back as integers whatever their width, and both float and double as floats,
because Elixir has neither a byte nor a 32-bit float — the same collapse
Latu.Column.lit/1 applies going out. A day_time_interval comes back as a count of
microseconds; Elixir's Duration is the obvious upgrade and waits on someone wanting
it.
A struct literal becomes a map with atom keys, as Latu.collect/2 does for a row. A
UDT-typed one becomes a Latu.Result.UDT instead, since it names a class and not fields.