带有中缀表示法的二进制运算符的索引族

时间:2014-01-15 10:20:11

标签: macros operators agda

假设您要定义一系列二元运算符(由集合索引,例如),其中参数的类型取决于索引的值,并且显式传递索引。此外,假设您希望该系列的成员可以使用中缀表示法:

x <[A] y

这是索引;括号[ - ]应该表示A应该被读作下标。为这种与此语法兼容的操作提供类型签名很困难,因为x的类型取决于 A,因此A : Set必须出现在x : A的左侧在_<[_]_

的定义中

我基于syntax声明尝试了以下技巧(黑客?):

cmp : (A : Set) → A → A → Set
cmp = {!!}

syntax cmp A x y = x <[ A ] y

postulate C : Set
postulate c : C

x = c <[ C ] c

除非您的二进制操作使用隐式实例,否则这似乎有效。如果我尝试将{{x}}形式的参数添加到syntax声明,Agda会抱怨。 (也许并非不合理。)

似乎可以通过引入cmp的版本来明确地采用隐式实例,然后定义调用该版本的语法变体:

postulate B : Set

-- Now expects an ambient B.
cmp : (A : Set) {{b : B}} → A → A → Set
cmp = {!!}

-- Version of cmp that makes implicit instance explicit.
cmp-explicit : (A : Set) (b : B) → A → A → Set
cmp-explicit A b = cmp A {{b}}

syntax cmp A x y = x <[ A ] y
syntax cmp-explicit A b x y = x <[ A at b ] y

postulate C : Set
postulate c : C
postulate b : B

x = c <[ C ] c       -- pick up ambient B
y = c <[ C at b ] c  -- pass B explicitly

(由于syntax似乎不支持{{x}}参数,因此无法将cmp内联到cmp-explicit,而不会放弃获取环境B的能力完全。)

这是一个黑客吗?当y的类型取决于x的值,并且显式传递x时,是否有另一种方法来翻转参数x和y?

当然,定义

_<′[_]_ = λ x A y → cmp A x y

导致Agda在类型检查x时抱怨。

1 个答案:

答案 0 :(得分:2)

你不能真正以A : Set x : A之后syntax的方式翻转参数。

您已经提到x <[ A ] y,我认为这是最佳解决方案。这是有效的,因为Agda会将cmp A x y转换为_<[_]_ : {A : Set} → A → ? → A → Set ,对于类型检查器来说这很好。

这是另一种(相当丑陋和黑客)的方法。假设我们有:

A

在这里我们可以稍微利用统一:通过在?洞中使用提及A的内容,我们可以强制类型检查器填充前面的隐式?。但据我所知,我们不能使用简单的类型代替x <[ A ] y,因此我们得到了所需的data Is : Set → Set₁ where is : (A : Set) → Is A _<[_]_ : {A : Set} → A → Is A → A → Set x <[ is A ] y = cmp A x y 。但要完成这个想法,这里有一件事是有效的:

syntax

是的,这是相当丑陋的,我建议不要这样做。


但回到关于syntax的问题:我不会认为syntax是任何方式的黑客攻击。事实上,标准库在一个地方使用Data.Plus的方式大致相同(确切地说syntax Plus R x y = x [ R ]⁺ y ):

cmp-explicit

即使cmp-syntax = cmp cmp-explicit-syntax = λ A b → cmp A {{b}} syntax cmp-syntax A x y = x <[ A ] y syntax cmp-explicit-syntax A b x y = x <[ A at b ] y 周围也很有用。我甚至会建议你再制作两个版本:

_<[_]_

如果模块的用户不想使用语法快捷方式(例如,他导入另一个定义cmp的模块),他只需选择不导入它,但仍然有Σ周围。

同样,标准库使用open import Data.Nat open import Data.Product open import Relation.Binary.PropositionalEquality x : Σ[ n ∈ ℕ ] n + 2 ≡ 4 x = 2 , refl 的语法快捷方式执行此操作。快捷方式允许您编写:

open import Data.Product
  hiding (Σ-syntax)

如果您不想要它,那么您只需:

{{1}}