Agda的Haskell派生机制

时间:2016-03-24 20:21:54

标签: haskell signature agda

我想知道Agda中是否有类似于Haskell deriving Eq条款的内容 - 然后我在下面也有一个相关的问题。

例如,假设我有玩具语言的类型,

data Type : Set where
  Nat  : Type
  Prp : Type

然后我可以通过模式匹配和C-c C-a

实现可判定的相等性
_≟ₜ_ : Decidable {A = Type} _≡_
Nat ≟ₜ Nat = yes refl
Nat ≟ₜ Prp = no (λ ())
Prp ≟ₜ Nat = no (λ ())
Prp ≟ₜ Prp = yes refl

我很好奇这是否可以机械化或自动化,与Haskell中的方式类似:

data Type = Nat | Prp deriving Eq

感谢 - 你!

虽然我们讨论类型的主题,但我想将我的正式类型视为Agda类型:Nat只是自然数,而Prp是小命题。

⟦_⟧Type : Type → Set ?
⟦ Nat ⟧Type = ℕ
⟦ Prp ⟧Type = Set

可悲的是,这不起作用。我尝试通过提升解决这个问题但失败了,因为我对如何使用水平提升没有任何线索。任何帮助表示赞赏!

上述功能的一个示例用法是,

record InterpretedFunctionSymbol : Set where
  field
   arity   : ℕ
   src tgt : Type
   reify   : Vec ⟦ src ⟧Type arity → ⟦ tgt ⟧Type

谢谢你让我感到羞耻!

2 个答案:

答案 0 :(得分:6)

" 7.3.2。派生数据类型的操作" A Cosmology of Datatypes章节介绍了如何使用描述推导出操作。但是,派生的Eq在那里相当薄弱。

基本思想是使用一些一阶编码表示数据类型,即根据某些通用数据类型,并定义对此数据类型的操作,因此根据它编码的所有内容都可以由这些通用操作处理。我详细阐述了这个机制的一个简单版本here

如果您拥有封闭的Universe,则可以派生出更强的Eq。使用类似于描述的方法(应该同样表达,但我没有检查)和封闭的宇宙我定义了通用show here,这允许例如在命名构造函数后打印元组向量:

instance
  named-vec : {A : Type} -> Named (vec-cs A)
  named-vec = record { names = "nil" ∷ "cons" ∷ [] }

test₂ : show (Vec (nat & nat) 3 ∋ (7 , 8) ∷ᵥ (9 , 10) ∷ᵥ (11 , 12) ∷ᵥ []ᵥ)
      ≡ "(cons 2 (7 , 8) (cons 1 (9 , 10) (cons 0 (11 , 12) nil)))"
test₂ = prefl

其中Vec的定义类似于Desc数据类型。 Eq案例应该类似,但更复杂。

以下是Lift的使用方法:

⟦_⟧Type : Type → Set₁
⟦ Nat ⟧Type = Lift ℕ
⟦ Prp ⟧Type = Set

ex₁ : ∀ A -> ⟦ A ⟧Type
ex₁ Nat = lift 0
ex₁ Prp = ℕ

ex₂ : ∀ A -> ⟦ A ⟧Type -> Maybe ℕ
ex₂ Nat n = just (lower n) -- or (ex₂ Nat (lift n) = just n)
ex₂ Prp t = nothing

如果A : Set α,则为Lift A : Set (α ⊔ ℓ) 。因此,当您有ℕ : SetSet : Set₁时,您希望将Set提升到Set₁,这只是Lift ℕ - 在简单的情况下您不需要明确提供

要构建包含在Lift中的数据类型的元素,请使用lift(如lift 0中所述)。要恢复此元素,请使用lower,因此liftlower相互反转。请注意lift (lower x)并不一定与x位于同一个Universe中,因为lift (lower x)"刷新"

更新show链接现已中断(我应该使用固定链接)。但现在有一个更好的示例:an entire library为常规Agda数据类型派生Eq

答案 1 :(得分:2)

对于在Agda中实际实现“派生Eq”,您可以在https://github.com/UlfNorell/agda-prelude查看Ulf的agda-prelude。特别是,模块Tactic.Deriving.Eq包含用于为一般类(简单和索引)数据类型自动生成可判定等式的代码。