Bin
is an inductive type that represents binary numbers.
inductive Bin where
| done
| zero : Bin → Bin
| one : Bin → Bin
def Bin.toString : Bin → String
| .done => ""
| .one b => b.toString ++ "1"
| .zero b => b.toString ++ "0"
instance : ToString Bin where
toString
| .done => "0"
| b => Bin.toString b
Binary numbers can be converted to natural numbers by repeatedly applying Bin.succ
:
def Bin.succ (b : Bin) : Bin :=
match b with
| .done => Bin.done.one
| .zero b => .one b
| .one b => .zero b.succ
def Bin.ofNat (n : Nat) : Bin :=
match n with
| 0 => .done
| n + 1 => (Bin.ofNat n).succ
Even if Bin.ofNat
is registered as a coercion, natural number literals cannot be used for Bin
:
attribute [coe] Bin.ofNat
instance : Coe Nat Bin where
coe := Bin.ofNat
#eval (failed to synthesize
OfNat Bin 9
numerals are polymorphic in Lean, but the numeral `9` cannot be used in a context where the expected type is
Bin
due to the absence of the instance above
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
9 : Bin)
failed to synthesize
OfNat Bin 9
numerals are polymorphic in Lean, but the numeral `9` cannot be used in a context where the expected type is
Bin
due to the absence of the instance above
Hint: Additional diagnostic information may be available using the `set_option diagnostics true` command.
This is because coercions are inserted in response to mismatched types, but a failure to synthesize an OfNat
instance is not a type mismatch.
The coercion can be used in the definition of the OfNat Bin
instance:
instance : OfNat Bin n where
ofNat := n
1010
#eval (10 : Bin)