为什么 Idris 将值名称与随后定义的类型参数名称混为一谈?

Why does Idris conflate a value name with a type argument name that is subsequently defined?

Haskell 允许:

a:: Int 
a = 3
data MyList a = Nil | Cons a (MyList a) 

而 Idris 会抱怨 a is bound as an implicit, 我需要使用不同类型的参数:

a: Int 
a = 3
data MyList b = Nil | Cons b (MyList b)

实际上,Idris 并没有在这里将它们混为一谈,因为 a 是小写的。但它 可以 – 除了 Haskell – 因为它支持类型中的值。所以编译器会警告你,因为这是错误的常见来源。假设你写:

n : Nat
n = 3

doNothing : Vect n Int -> Vect n Int
doNothing xs = xs

您可能认为 doNothing 的类型是 Vect 3 Int -> Vect 3 Int。但是 lower case arguments are bound to be implicitdoNothing 的类型实际上是 {n : Nat} -> Vect n Int -> Vect n Int,尽管之前声明了 n。您必须写成 Vect Main.n IntN 大写才能使用它。

所以编译器认为你可能想做一些与 MyList a 中的 a 类似的事情并警告你。