说,我想定义一种证明向量具有一定总和的证明类型。我也希望该证明适用于任何Monoid
类型的t
。我的第一次尝试是:
data HasSum : Monoid t => t -> Vect n t -> Type where
EndNeutral : Monoid t => HasSum Prelude.Algebra.neutral []
Component : Monoid t => (x : t) -> HasSum sum xs -> HasSum (x <+> sum) (x :: xs)
不幸的是,编译器认为Can't find implementation for Monoid t
。因此,我尝试使用隐式参数,以便可以指定其类型:
EndNeutral : Monoid t => {Prelude.Algebra.neutral : t} -> HasSum Prelude.Algebra.neutral []
这会编译,但是不会:
x : HasSum 0 []
x = EndNeutral
奇怪地声称它Can't find implementation for Monoid Integer
。
我最后的尝试是定义一个带有大写字母名称的辅助常量,以使Idris不会将其混淆为绑定变量:
ZERO : Monoid t => t
ZERO = neutral
data HasSum : Monoid t => t -> Vect n t -> Type where
EndNeutral : Monoid t => HasSum ZERO []
Component : Monoid t => {rem : t} -> (x : t) -> HasSum rem xs -> HasSum (x <+> rem) (x :: xs)
但是现在它无法猜测ZERO
(EndNeutral
)的定义中Can't find implementation for Monoid t
的类型。因此,我再次尝试使用隐式绑定:
EndNeutral : Monoid t => {ZERO : t} -> HasSum ZERO []
但是现在ZERO
成为一个绑定变量,尽管可以编译,但它不能按预期工作,因为它允许构造具有任意和的空向量的证明。
在这一点上,我没有想法了。有谁知道如何以Idris类型表示多态常数?
答案 0 :(得分:0)
看来我终于找到了答案。它可能不是最好的,但它是我目前所知道的唯一一个。因此,需要在不添加隐式参数的情况下明确指定neutral
的类型(这将把neutral
变成绑定变量)。当然,功能the
可以达到这个目的:
data HasSum : Monoid t => t -> Vect n t -> Type where
EndNeutral : Monoid t => HasSum (the t Prelude.Algebra.neutral) []
Component : Monoid t => {rem : t} -> (x : t) -> HasSum rem xs -> HasSum (x <+> rem) (x :: xs)
编辑:
看看neutral
的类型提出了另一种解决方案:
> :doc neutral
Prelude.Algebra.neutral : Monoid ty => ty
看来neutral
的具体类型实际上是它的隐式参数。因此:
EndNeutral : Monoid t => HasSum (Prelude.Algebra.neutral {ty = t}) []
也可以。