Agda型安全铸造/强制

时间:2015-01-05 21:54:02

标签: agda

我发现了一个方便的功能:

coerce : ∀ {ℓ} {A B : Set ℓ} → A ≡ B → A → B
coerce refl x = x

定义具有索引类型的函数时。在索引在定义上不相等的情况下,i,e,必须使用引理来显示类型匹配。

zipVec : ∀ {a b n m } {A : Set a} {B : Set b} → Vec A n → Vec B m → Vec (A × B) (n ⊓ m)
zipVec [] _ = []
zipVec {n = n} _ [] = coerce (cong (Vec _) (0≡n⊓0 n)) []
zipVec (x ∷ xs) (y ∷ ys) = (x , y) ∷ zipVec xs ys

注意,但这个例子很容易重写,所以不需要强制:

zipVec : ∀ {a b n m } {A : Set a} {B : Set b} → Vec A n → Vec B m → Vec (A × B) (n ⊓ m)
zipVec [] _ = []
zipVec (_ ∷ _) [] = []
zipVec (x ∷ xs) (y ∷ ys) = (x , y) ∷ zipVec xs ys

有时模式匹配无济于事。

问题:但我想知道,这个功能之类的东西是否已经在agda-stdlib?对于Agda,有什么类似 hoogle 的东西,或类似 SearchAbout 的东西吗?

1 个答案:

答案 0 :(得分:5)

我不认为你的coerce功能正是如此。然而,它是subst的一个更通用的函数 - Relation.Binary.PropositionalEquality(平等的替代属性)的一个特例:

subst : ∀ {a p} {A : Set a} (P : A → Set p) {x y : A}
      → x ≡ y → P x → P y
subst P refl p = p

如果您选择P = id(来自Data.Function,或只是写λ x → x),则会获得:

coerce : ∀ {ℓ} {A B : Set ℓ} → A ≡ B → A → B
coerce = subst id

顺便说一句,您最不可能找到预定义此功能的原因是Agda通过coerce处理rewrite这样的问题:

postulate
  n⊓0≡0 : ∀ n → n ⊓ 0 ≡ 0

zipVec : ∀ {a b n m} {A : Set a} {B : Set b}
       → Vec A n → Vec B m → Vec (A × B) (n ⊓ m)
zipVec [] _ = []
zipVec {n = n} _ [] rewrite n⊓0≡0 n = []
zipVec (x ∷ xs) (y ∷ ys) = (x , y) ∷ zipVec xs ys

这是一个更复杂的语法糖:

zipVec {n = n} _ [] with n ⊓ 0 | n⊓0≡0 n
... | ._ | refl = []

如果您熟悉with的工作原理,请尝试弄清楚rewrite的工作原理;它很有启发性。