【问题标题】:Haskell Deriving Mechanism for AgdaAgda 的 Haskell 推导机制
【发布时间】:2016-07-12 14:00:37
【问题描述】:

我想知道 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

谢谢你逗我开心!

【问题讨论】:

    标签: haskell signature agda


    【解决方案1】:

    A Cosmology of Datatypes 的“7.3.2. 对数据类型派生操作”一章展示了如何使用描述派生操作。不过,派生的Eq 在那里相当弱。

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

    如果你有一个封闭的宇宙,你可以推导出一个更强的Eq。使用类似于描述的方法(应该同样具有表现力,但我没有检查)和一个封闭的宇宙,我定义了通用showhere,它允许例如在命名构造函数后打印元组向量:

    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 在同一个宇宙中,因为lift (lower x)“刷新”

    更新show 链接现在已损坏(我应该使用永久链接)。但现在有一个更好的例子:an entire library 派生出 Eq 用于常规 Agda 数据类型。

    【讨论】:

    • 非常感谢;期待阅读被引论文和被引博客^_^
    【解决方案2】:

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

    【讨论】:

    • 它是否能够派生Eq (Vec A n) 在范围内具有Eq A
    猜你喜欢
    • 2013-09-01
    • 2016-03-23
    • 2012-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-26
    • 2013-08-19
    • 1970-01-01
    相关资源
    最近更新 更多