hanki

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.