-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-- https://hirrolot.github.io/posts/why-static-languages-suffer-from-complexity.html
inductive Fmt where
| Arg : Fmt → Fmt
| Nat : Fmt → Fmt
| Char : Char → Fmt → Fmt
| End
def toFmt : List Char → Fmt
| '*' :: xs => .Arg <| toFmt xs
| '#' :: xs => .Nat <| toFmt xs
| x :: xs => .Char x <| toFmt xs
| [] => .End
def PrintfType : Fmt → Type 1
| .Arg fmt => {α : Type} → [ToString α] → α → PrintfType fmt
| .Nat fmt => Nat → PrintfType fmt
| .Char _ fmt => PrintfType fmt
| .End => PLift String
def printf (fmt : String) : PrintfType <| toFmt fmt.toList :=
let rec printfAux (acc : Array Char) : (fmt : Fmt) → PrintfType fmt
| .Arg fmt => fun x ↦ printfAux (acc ++ (toString x).toList) fmt
| .Nat fmt => fun x ↦ printfAux (acc ++ (toString x).toList) fmt
| .Char c fmt => printfAux (acc.push c) fmt
| .End => .up acc.toList.asString
printfAux #[] <| toFmt fmt.toList
#eval printf "Hello * # * *" (-1) 1 [42, 69] "Meow" |>.down