有没有办法让函数要求两个Setoid
s,其中第一个Setoid
中的相等意味着后者中的相等?当然,这要求Setoid
分享Carrier
和Carrier
不是参数,而是记录字段。请求Carrier
平等的天真尝试被类型检查器拒绝:
f : {S₁ S₂ : Setoid _ _} → Setoid.Carrier S₁ ≡ Setoid.Carrier S₂ →
({x y : Setoid.Carrier S₁} → Setoid._≈_ S₁ x y → Setoid._≈_ S₂ x y ) → ...
这不起作用,因为我们在等式证明上没有模式匹配,因此不同的Carrier
类型不统一。我还没有找到使用subst
来表达这一点的方法。
答案 0 :(得分:1)
您有两种选择。我正在使用以下快捷方式:
A = Setoid.Carrier S₁
B = Setoid.Carrier S₂
您可以将元素x
和y
从A
传输到B
,也可以从Setoid._≈_ S₂
传输B → B → Set _
关系到A → A → Set _
。
运输元素可以通过subst id
:
f : ∀ {c ℓ} {S₁ S₂ : Setoid c ℓ}
(p : Setoid.Carrier S₁ ≡ Setoid.Carrier S₂) →
(∀ {x y} → Setoid._≈_ S₁ x y →
Setoid._≈_ S₂ (subst id p x) (subst id p y)) →
?
请注意subst id : A ≡ B → A → B
(大致)。
然后可以通过subst (λ x → x → x → Set _)
传输整个关系。我们从B → B → Set _
开始,因此我们需要一个证明B ≡ A
而不是A ≡ B
- 这就是我们使用sym
的原因:
g : ∀ {c ℓ} {S₁ S₂ : Setoid c ℓ}
(p : Setoid.Carrier S₁ ≡ Setoid.Carrier S₂) →
(∀ {x y} → Setoid._≈_ S₁ x y →
subst (λ x → x → x → Set _) (sym p) (Setoid._≈_ S₂) x y) →
?
很难说哪一个更容易使用。另一种选择是直接使用IsEquivalence
,这允许您简单地强制关系在同一个域上:
h : ∀ {a ℓ} {A : Set a} {_≈₁_ _≈₂_ : Rel A ℓ}
{E₁ : IsEquivalence _≈₁_} {E₂ : IsEquivalence _≈₂_} →
(∀ {x y} → x ≈₁ y → x ≈₂ y) →
?