display
stdlib/display.hk: the Display trait and its builtin impls.
Used by string interpolation lowering and by Hanki programs that want to format their own types. The int/i32/decimal/rational/f64/bool impls are @intrinsic: the runtime supplies the conversion directly, with no body needed. The other fixed-width integer widths render by widening (always exact) to one of those, and they need no native seam of their own.
Display
trait Display
to_string
def to_string(self) -> string
Renders a value as a string. String interpolation #{x} desugars through this trait.
42i32.to_string() => "42"
(-7i32).to_string() => "-7"
impl Display<i32>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
0i32.to_string() => "0"
2147483647i32.to_string() => "2147483647"
impl Display<int>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
42.to_string() => "42"
(-7).to_string() => "-7"
impl Display<i8>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
0i8.to_string() => "0"
127i8.to_string() => "127"
(-128i8).to_string() => "-128"
impl Display<i16>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
32767i16.to_string() => "32767"
(-32768i16).to_string() => "-32768"
impl Display<i64>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
9223372036854775807i64.to_string() => "9223372036854775807"
(-9223372036854775808i64).to_string() => "-9223372036854775808"
impl Display<u8>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
0u8.to_string() => "0"
255u8.to_string() => "255"
impl Display<u16>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
65535u16.to_string() => "65535"
impl Display<u32>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
4294967295u32.to_string() => "4294967295"
impl Display<u64>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
18446744073709551615u64.to_string() => "18446744073709551615"
impl Display<decimal>
to_string
def to_string(self) -> string
Renders the number as its decimal text.
d: decimal = 3.14
d.to_string() => "3.14"
impl Display<rational>
to_string
def to_string(self) -> string
A rational renders in lowest terms; an integral one elides the denominator.
r: rational = 1 / 3
r.to_string() => "1/3"
whole: rational = 6 / 2
whole.to_string() => "3"
impl Display<f64>
to_string
def to_string(self) -> string
The shortest decimal that round-trips back to the same f64; an integral value elides the fraction (1.0 renders as "1"). Non-finite values render as inf / -inf / NaN.
0.5f64.to_string() => "0.5"
(-2.5f64).to_string() => "-2.5"
100.25f64.to_string() => "100.25"
impl Display<f32>
to_string
def to_string(self) -> string
The shortest decimal that round-trips back to the same f32 (rendered on the f32 grid and never f64's: 0.1f32 is "0.1", and no 0.10000000149…).
0.5f32.to_string() => "0.5"
(-2.5f32).to_string() => "-2.5"
impl Display<bool>
to_string
def to_string(self) -> string
Renders true or false.
true.to_string() => "true"
false.to_string() => "false"
impl Display<string>
to_string
def to_string(self) -> string
The identity: a string renders as itself.
"hello".to_string() => "hello"
impl Display<()>
to_string
def to_string(self) -> string
The two characters (), which is how the source spells the value.
Unlike Eq<()> and Hash<()>, being a singleton does not decide this. What a unit should print is a free choice. The derive decides it: a @derive(Display) over a struct with a unit field has to print something for that field, and () is the only spelling that round-trips to the source. Using the same text here makes the derived and the direct rendering agree, which every other type already manages.
().to_string() => "()"
roundtrips?
def _round_trips?<T: Display + FromString>(x: T) -> bool
The law Display and FromString promise each other, written as a render fixpoint and no value equality: decimal and rational have no Eq impl, parse(render(x)) == x cannot be stated for the whole tower, and rendering the parse back and comparing strings can, saying the same thing wherever both can be written.
roundtripsbyvalue?
def _round_trips_by_value?<T: Display + FromString + Eq>(x: T) -> bool
The same law as value equality, for the types that can state it. Strictly stronger than the fixpoint: a Display that dropped a leading digit would render 1234 as "234", which parses to 234 and renders back to "234" - a fixpoint the round trip passes and this does not. decimal and rational have no Eq impl, and the fixpoint exists for them; everything that has one is held to this too.