In order to get acquainted with Lean and programming with dependent types I am trying to implement basic operations for a Vector
datatype defined following the example in TPiL as:
inductive Vector (α : Type u) : Nat → Type u
| nil : Vector α 0
| cons : α → {n : Nat} → Vector α n → Vector α (n+1)
I tried implementing an append
function to concatenate two vectors as
def append : Vector α m → Vector α n → Vector α (m + n)
| nil, v => v
| cons h t, v => cons h (append t v)
but in the nil
case I get the error
type mismatch
v
has type
Vector α n : Type ?u.1240
but is expected to have type
Vector α (0 + n) : Type ?u.1240
The type checker apparently can't tell that Vector α n
and Vector α (0 + n)
are the same type. It works if I instead change the type of append
to Vector α m → Vector α n → Vector α (n + m)
, so that the expected type is Vector α (n + 0)
. So apparently it can't tell that addition is commutative.
If I do change the type to Vector α (n + m)
, then later when I use it to implement a function to reverse a vector it fails to type check again:
def reverse : {n : Nat} -> Vector α n → Vector α n
| 0, nil => nil
| n' + 1, cons h t => append (reverse t) (cons h nil)
The reason is that on the recursive call it expects reverse t
to be of type Vector α 1
and cons h nil
to be of type Vector α n'
(rather than the other way around) so that the result will have type Vector α (n' + 1)
(rather than Vector α (1 + n')
). So again the problem is that it doesn't realize that addition is commutative.
What do I have to do to get the type checker to understand that Vector α (m + n)
is the same as Vector α (n + m)
?
n+0
withn
because its by definition of addition, whereas0+n
does not reduce ton
. The distinction is that the former equality is definitional, and the latter is semantic. The typechecker cannot decide equality of semantically equal terms, hence also whyn+m
cannot be identified withm+n
. $\endgroup$n+m = m+n
. Is there any way to use this proof to guide the type checker, for example? $\endgroup$p : x = x
thenp = Eq.refl x
, definitionally), which sort of annihilates any complications to equality beyond "you have to be explicit about where you substitute equalities". $\endgroup$