import Lean structure Vec2 where (x y : Float) instance : Add Vec2 := ⟨λ ⟨x₁,x₂⟩ ⟨y₁, y₂⟩ => ⟨x₁+y₁, x₂+y₂⟩⟩ instance : HMul Float Vec2 Vec2 := ⟨λ s ⟨x₁,x₂⟩ => ⟨s*x₁, s*x₂⟩⟩ def NFloatArray (n : Nat) := {a : FloatArray // a.size = n} instance {n} : Add (NFloatArray n) := ⟨λ x y => Id.run do let mut x := x.1 for i in *...n do x := x.set i (x[i]'sorry+y.1[i]'sorry) sorry ⟨x,sorry⟩⟩ instance {n} : HMul Float (NFloatArray n) (NFloatArray n) := ⟨λ s x => Id.run do let mut x := x.1 for i in *...n do x := x.set i (s*x[i]'sorry) sorry ⟨x,sorry⟩⟩ def FloatVector : Nat → Type | 0 => Unit | 1 => Float | 2 => Vec2 | (n+3) => NFloatArray (n+3) @[inline] def FloatVector.add {n : Nat} (x y : FloatVector n) : FloatVector n := match n with | 0 => Unit.unit | 1 => by unfold FloatVector at x y; apply x + y | 2 => by unfold FloatVector at x y; apply x + y | (_+3) => by unfold FloatVector at x y; apply x + y def FloatVector.smul {n : Nat} (s : Float) (x : FloatVector n) : FloatVector n := match n with | 0 => Unit.unit | 1 => by unfold FloatVector at x; apply s*x | 2 => by unfold FloatVector at x; apply s*x | (_+3) => by unfold FloatVector at x; apply s*x instance : Add (FloatVector n) := ⟨λ x y => x.add y⟩ instance : HMul Float (FloatVector n) (FloatVector n) := ⟨λ s x => x.smul s⟩ def foo1 := λ (x y : FloatVector 2) => x + y def foo2 := λ {n} (s : Float) (x y : FloatVector n) => s * (x + y) run_meta Lean.Compiler.compile #[``foo1] run_meta Lean.Compiler.compile #[``foo2] set_option trace.Compiler.result true set_option pp.funBinderTypes true run_meta Lean.Compiler.compile #[``foo1] run_meta Lean.Compiler.compile #[``foo2]