实例搜索限制

时间:2015-07-21 16:32:19

标签: agda

旧的paperat the Agda wiki中描述了实例参数机制。这些消息来源没有提到一些值得注意的事实吗?实例搜索有哪些限制?

1 个答案:

答案 0 :(得分:5)

消除歧义

如果我们检查这个:

open import Category.Functor
open import Category.Monad
open RawFunctor
open RawMonad

并运行C-c C-w _<$>_C-c C-w是&#34;解释为什么范围内的特定名称&#34;),我们得到(经过一些清理)

_<$>_ is in scope as
  * a record field Category.Functor.RawFunctor._<$>_
  * a record field Category.Monad.RawMonad._._<$>_

即。 _<$>_含糊不清,因此在同一模块中使用不是monad的monad和functor很麻烦,因为你必须手动消除两个_<$>_之间的歧义。

这可以通过实例参数来解决。而不是在Functor(通过Monad)的定义中打开Applicatve

record RawIMonad ... where

  open RawIApplicative rawIApplicative public

我们可以提供一个实例,让实例搜索完成工作(可以找到ApplicativeFunctor的定义here):

record Monad {α} (M : Set α -> Set α) : Set (suc α) where
  infixl 1 _>>=_

  field
    return : ∀ {A} -> A -> M A
    _>>=_  : ∀ {A B} -> M A -> (A -> M B) -> M B

  instance
    Monad<:Applicative : Applicative M
    Monad<:Applicative = record { pure = return ; _<*>_ = λ mf mx -> mf >>= λ f -> mx >>= return ∘ f }
open Monad {{...}}

现在只有一个_<$>_ - 在Functor的定义中,但是实例搜索看到,monad是一个应用程序,applicative是一个functor,所以定义了_<$>_在monad上,因为它是在仿函数上定义的。

实例字段

目前,您can't将记录字段声明为实例:

record R : Set where
  field
    instance n : ℕ

解决方法是

record R : Set where
  field
    n : ℕ

   instance
     R->ℕ : ℕ
     R->ℕ = n

弱点

实例搜索与metavariables解析不合作。

instance
  fz : Fin 1
  fz = zero

z : ∀ {n} {{_ : Fin n}} -> ℕ
z = 0

yellow : z ≡ 0
yellow = refl

ok : z {1} ≡ 0
ok = refl

yellow实例中,搜索无法找到fz实例。我was told,这是预期的行为,但对我来说看起来过于严格,我看不到任何好处。

一种解决方法是使用实​​例参数代替隐式参数:

instance
  one : ℕ
  one = 1

  fz : Fin 1
  fz = zero

  z : ∀ {{n}} {{_ : Fin n}} -> ℕ
  z = 0

  now-ok : z ≡ 0
  now-ok = refl

Instances are always imported

module M where
  instance
    z : ℕ
    z = 0

z' : {{n : ℕ}} -> ℕ
z' {{n}} = n

ok : z' ≡ 0
ok = refl

M模块未打开,但实例在范围内。如果要隐藏实例,请使用记录:

record R : Set where
  instance
    z : ℕ
    z = 0

z' : {{n : ℕ}} -> ℕ
z' {{n}} = n

error : z' ≡ 0
error = refl

open R _

ok : z' ≡ 0
ok = refl

A nasty bug

我们可以将ok重写为

ok : let open R _ in z' ≡ 0
ok = refl

但是如果定义下面的ok'

ok' : z' ≡ 0
ok' = refl

来自R的实例不在范围内,但无论如何Agda都会选择它。价值水平也是如此。即如果您导入模块或打开记录,则无论您在何处打开它,下面的所有定义都可以使用该模块中的实例。

个人经历

我正在与实例论证进行为期两周左右的斗争,在Agda中试图implement一些基本类别理论,但实例搜索由于其弱点而无法预测 - 在记录中添加一个参数会破坏一切。它也很难理解为什么一切都是黄色的 - 是因为你做的事情愚蠢还是因为Agda拒绝解决一个微不足道的元变量?如果你有六行和几个嵌套记录的类型签名,那么运气问题,是否能找到克服实例搜索限制的方法。