假设您要定义一系列二元运算符(例如,由集合索引),其中参数的类型取决于索引的值,并且索引是显式传递的。此外,假设您希望家庭成员可以使用中缀表示法:
x <[A] y
A 这里是索引;括号 [-] 应该表明 A 应该被读作下标。为与此语法兼容的此类操作提供类型签名很困难,因为 x 的类型取决于值A,因此A : Set
必须出现x : A
在 的定义的左侧_<[_]_
。
我已经根据syntax
声明尝试了以下技巧(hack?):
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
。