Agda stdlib Vec 在列表上执行 fromList 后最后一次调用

Agda stdlib Vec calling last after doing fromList on a List

我有以下功能:

natListLast : List ℕ → ℕ
natListLast nats = v.last (v.fromList nats)

我目前收到此错误:

l.foldr (λ _ → suc) 0 nats != suc _n_126 of type ℕ
when checking that the expression fromList nats has type
Vec ℕ (1 + _n_126)

我想知道当 v.fromList returns Vec A (length xs) 时如何在 v.fromList nats 上调用 last。我如何告诉编译器 length xs 等于 1 + _n_126

谢谢!

我也试过:

natListLast : List ℕ → ℕ
natListLast nats = v.last {l.length nats} (v.fromList nats)

因为 last 有这个签名:

last : ∀ {n} → Vec A (1 + n) → A

我认为我可以将 nats 的长度作为 last 的隐式参数传入,但我收到此错误:

ℕ !=< Level
when checking that the inferred type of an application
  ℕ
matches the expected type
  Level

How can I tell the compiler that length xs is equal to 1 + _n_126?

想一想这个问题。 怎么知道length xs等于1 + _n_126?如果 xs = []length xs = 0 怎么办?答案是你做不到,所以也不要指望 Agda 会这样做!

要解决此问题,您需要在 xs 上进行模式匹配以确保它不为空:

natListLast : List ℕ → ℕ
natListLast nats@(x ∷ xs) = v.last (v.fromList nats)
natListLast []            = {!!}

在第二种情况下 return 由你决定。


对于第二个问题,您需要检查 last 的完整类型(在 Emacs 中使用 C-c C-d):

{A.a : Agda.Primitive.Level} {A : Set A.a} {n : ℕ} →
v.Vec A (suc n) → A

如您所见,在长度 n 之前有两个隐藏参数(它们已由 automatic variable generalization 插入)。要直接传递参数 n 而不传递前两个参数,您可以命名参数,例如 last {n = l.length nats}.