对 Idris 中的中间类型感到困惑

Confused about an intermediate type in Idris

我正在尝试实现一个玩具常规类型系统,以确保一些良好的形式侧约束并允许在其中展开 mu 绑定。表示这些类型的数据类型包含定点构造函数 (Mu)、由最近的封闭 Mu-bound 项替换 (Var) 以及零和一个参数类型运算符 (NullaryUnary,分别)。

为了确保某些类型的格式正确,它们会作为三个 Bool 参数跟踪它们是否有一个 Mu 作为它们的头部构造函数,一个 Var 作为它们的头部构造函数,或其中任何位置的 Var

data A : Bool -- Is Mu headed?
      -> Bool -- Is Var headed?
      -> Bool -- Contains any Var's?
      -> Type where
Mu : A False False _ -> A True False False
Var : A False True True
Nullary : A False False False
Unary : A _ _ m -> A False False m

要实现 Mu-headed 类型的展开,我需要执行替换,具体来说,我需要实现 "Mu x. F ====> F[(Mu x. F)/x]".

除了需要一些东西来生成证明第三种类型参数有效之外,函数 subst 看起来很简单:

total subst : A m1 v1 c1 -> A m2 v2 c2 -> (c3 ** ((A (m2 || (v2 && m1)) 
                                                     (v2 && v1) 
                                                     c3)
                                             ,(c3 = (c2 && c1))))
subst _ Nullary = (_ ** (Nullary,Refl))
subst w (Unary a) with (subst w a)
  | (c3** (a',aeq)) = (c3 ** (Unary a',aeq))
subst w Var = (_ ** (w,Refl))
subst w (Mu a) = (_ ** (Mu a,Refl))

我尝试编写了一个包装器来清理这个 return 类型,但失败了。

total subst' : A m1 v1 c1 -> A m2 v2 c2 -> A (m2 || (v2 && m1)) 
                                             (v2 && v1) 
                                             (c2 && c1)
subst' a1 a2 with (subst a2 a2)
  | (_**(a',aeq)) ?=  a'

当我尝试解决这个元变量时,我发现 aeq : x = c2 && Delay c2 不是我预期的 aeq : x = c2 && Delay c1(回想一下 (&&) 在它的第二个参数中是惰性的)。

我是不是做错了什么?这是预期的行为吗? FWIW,我成功地为展开(未显示)编写了一个非常相似的包装器。

我想问题出在线路上

subst' a1 a2 with (subst a2 a2)

你不是要在 a1a2 上调用 subst 吗?