在 Idris 中为依赖对实现半群

Implementing Semigroup for dependent pair in Idris

我正在尝试为 Idris 中的简单依赖对实现 Semigroup 接口,但这无法编译:

Semigroup (n ** Vect n f) where
  (<+>) (_ ** xs) (_ ** ys) = (_ ** xs ++ ys)

错误

Type mismatch between
    ty
and
    Nat

但是这个编译:

myPair:Type -> Type
myPair f = (n ** Vect n f)

Semigroup (myPair f) where
   (<+>) (_ ** xs) (_ ** ys) = (_ ** xs ++ ys)

为什么?完成此任务的最佳方法是什么?

伊德里斯FAQ:

If you use a name in a type which begins with a lower case letter, and which is not applied to any arguments, then Idris will treat it as an implicitly bound argument.

解决该问题的一种方法是摆脱一些语法糖并像这样显式绑定 n

Semigroup (DPair Nat (\n => Vect n f)) where
  (<+>) = (_ ** xs) (_ ** ys) = (_ ** xs ++ ys)

另一种方法是对向量​​长度使用大写字母:

Semigroup (N ** Vect N f) where
  (<+>) = (_ ** xs) (_ ** ys) = (_ ** xs ++ ys)

在这里,N 没有在 Semigroup 实现中绑定,这允许 DPair 语法糖像我们一样启动并绑定 N在第一个变体中。

至于 myPair 示例,它可以编译,因为该示例本质上等同于上面的 DPair 示例。如果你只是去掉糖,一切都会变得清晰:

myPair:Type -> Type
myPair f = DPair Nat (\n => Vect n f)