是否可以定义一个简单的语法概念(类似于GHC可能自动派生为Haskell 98类型的Eq
实例),没有明确证明每个数据构造函数是单射的,或做类似的事情,比如定义每个构造函数的撤销并使用cong
?
换句话说,是否有可能更直接地利用数据构造函数的注入性,而不是必须为每个构造函数引入一个辅助函数?
以下以自然数为例。
module Eq where
open import Function
open import Relation.Binary
open import Relation.Binary.PropositionalEquality
open import Relation.Nullary
data ℕ : Set where
zero : ℕ
suc : ℕ → ℕ
-- How to eliminate these injectivity proofs?
suc-injective : ∀ {n m} → suc n ≡ suc m → n ≡ m
suc-injective refl = refl
_≟_ : Decidable {A = ℕ} _≡_
zero ≟ suc _ = no (λ ())
suc _ ≟ zero = no (λ ())
zero ≟ zero = yes refl
suc n ≟ suc m with n ≟ m
suc n ≟ suc .n | yes refl = yes refl
... | no n≢m = no (n≢m ∘ suc-injective)
可以用suc-injective
替换cong (λ { zero → zero ; (suc x) → x })
,即通过定义一个反转suc
的函数,但是每个构造函数仍然需要一个辅助函数的样板,这样的函数有点难看定义因为需要总计。
(通常需要注意的是缺少明显适用的东西。)
答案 0 :(得分:4)
Ulf Norell的prelude for Agda包含一种自动导出给定数据类型的可判定等式的机制。该代码基于Agda的反射机制,并自动生成扩展的lambdas,用于证明构造函数的注入性。我建议看看代码,尽管它并不总是那么简单。