Почему, конечно:
xszs : {A : Type} -> {len, len' : Nat} ->
(xs, ys : Vect len A) -> (zs : Vect len' A) ->
len = len' ->
xs = ys -> ys = zs ->
xs = zs
xszs {A} {len} {len'=len} xs ys zs Refl = trans
Я думаю, важно знать, что это в основном имеет , чтобы быть функцией. Вы не можете использовать sameLen
доказательство для замены len
на len'
в типах вещей, которые уже находятся в области видимости. То есть, если бы все ваши подписи были высшего уровня, Идрис никогда бы не убедился в том, что zs : Vect len a
. Вы должны использовать вспомогательную функцию. В вышеприведенной функции len'
сопоставляется с len
, что подтверждается соответствием Refl
до введения переменной zs
. Вы можете утверждать, что это явно неверно, так как zs
предшествует аргументу Refl
, но, поскольку Idris - тотальный язык, компилятору разрешено упростить вам жизнь, неявно переупорядочив абстракцию, сопоставление и весь этот джаз. , Фактически, непосредственно перед совпадением Refl
, до введения zs
, тип цели - (zs : Vect len' A) -> xs = ys -> ys = zs -> xs = zs
, но при совпадении это переписывается на (zs : Vect len A) -> ?etc
, а zs
вводится с более приятным типом.
Обратите внимание, что вещь len = len'
на самом деле просто не нужна. Это работает:
xszs : {A : Type} -> {len, len' : Nat} ->
(xs, ys : Vect len A) -> (zs : Vect len' A) ->
xs = ys -> ys = zs -> xs = zs
xszs {A} {len} {len'=len} xs xs xs Refl Refl = Refl
Или даже
xszs : {A : Type} -> {len, len' : Nat} ->
(xs, ys : Vect len A) -> (zs : Vect len' A) ->
xs = ys -> ys = zs -> xs = zs
xszs xs ys zs = trans