Cryptic error: `.A !=< .A₁ of type Set` in simple function

Cryptic error: `.A !=< .A₁ of type Set` in simple function

以下 Agda 函数应该查找列表,在索引溢出时循环:

module Test where

open import Prelude.Nat
open import Prelude.List

roundIndex : {A : Set} -> Nat -> A -> List A -> A
roundIndex n x xs = go n xs where
  go : {A : Set} -> Nat -> List A -> A
  go (suc n) (x ∷ xs) = go n xs
  go (suc n) []       = go n xs
  go zero    (x ∷ xs) = x
  go zero    []       = x

但不会编译并出现以下神秘错误:

/Users/v/vic/dev/agda/Test.agda:10,25-32
.A !=< .A₁ of type Set
when checking that the expression go n xs has type .A₁

似乎 Agda 没有正确地将隐式 A 传递给 go,但显式传递它并没有解决问题。这是什么错误?另外,就是 !=<?

错误是 go 适用于任何 A,但您尝试 return 外部 xxs 外部 A 类型。 go-bound AroundIndex-bound A 类型不同,因此会出现错误。通常,绑定类型变量仅在转换检查期间与自身相等。它不是 Agda-specific,因为您也可以在 Haskell 中重现相同的错误。

解决方法是去除内部类型量化:

roundIndex : {A : Set} -> Nat -> A -> List A -> A
roundIndex {A} n x xs = go n xs where
  go : Nat -> List A -> A
  go (suc n) (x ∷ xs) = go n xs
  go (suc n) []       = go n xs
  go zero    (x ∷ xs) = x
  go zero    []       = x

现在只有一个共享 A 周围。