为我自己的平等使用重写?

Using rewrite for my own equality?

我对等式的定义如下:

data Equal : x -> y -> Type where
    Reflexive : Equal a a

每当我想使用 rewrite 语法时,我都需要 (a = b) 类型的东西,所以我创建了:

makeEquitable : Equal x y -> x = y
makeEquitable Reflexive = Refl

现在我可以做 makeEquitable (_ : Equal a b),然后我可以用它来做 rewrite 事情。我想对此进行简化,然后我研究了 replace,但我并不真正理解 replace : (x = y) -> P x -> P y。这个 P 东西是一个内置的 Idris 属性 我假设 - 我将如何为我自己的定义制作这样的功能 Equality - 是否也可以 "bake-in" 一些特别的东西这样 rewrite 就会神奇地为 Equal a b?

工作

如果您在 repl 中设置 :set showimplicits,您会看到 :t replace 的隐式参数:

replace : {a : Type} -> {x : a} -> {y : a} -> {P : a -> Type} ->
          ((=) {A = a} {B = a} x y) -> P x -> P y

P 没有什么特别之处,它只是一个隐式参数:一个谓词 P 保留类型 a 的值。可以推断出这些隐式参数的大多数类型,因此您的函数可能如下所示:

replaceEqual : {P : a -> Type} -> Equal x y -> P x -> P y
replaceEqual Reflexive prf = prf

但据我所知,您无法轻易地制作自己的 rewrite。但是,您可以使用语法规则来美化您的方法:

syntax eqrewrite [a] "in" [b] = rewrite makeEquitable a in b;

plus_commutes_Z' : Equal m (plus m 0)
plus_commutes_Z' {m = Z} = Reflexive
plus_commutes_Z' {m = (S k)} =
  let rec = plus_commutes_Z' {m=k}
  in eqrewrite rec in Reflexive