旧的paper和at the Agda wiki中描述了实例参数机制。这些消息来源没有提到一些值得注意的事实吗?实例搜索有哪些限制?
答案 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
我们可以提供一个实例,让实例搜索完成工作(可以找到Applicative
和Functor
的定义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
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
我们可以将ok
重写为
ok : let open R _ in z' ≡ 0
ok = refl
但是如果定义下面的ok'
ok' : z' ≡ 0
ok' = refl
来自R
的实例不在范围内,但无论如何Agda都会选择它。价值水平也是如此。即如果您导入模块或打开记录,则无论您在何处打开它,下面的所有定义都可以使用该模块中的实例。
我正在与实例论证进行为期两周左右的斗争,在Agda中试图implement一些基本类别理论,但实例搜索由于其弱点而无法预测 - 在记录中添加一个参数会破坏一切。它也很难理解为什么一切都是黄色的 - 是因为你做的事情愚蠢还是因为Agda拒绝解决一个微不足道的元变量?如果你有六行和几个嵌套记录的类型签名,那么运气问题,是否能找到克服实例搜索限制的方法。