对 Idris 中的中间类型感到困惑
Confused about an intermediate type in Idris
我正在尝试实现一个玩具常规类型系统,以确保一些良好的形式侧约束并允许在其中展开 mu 绑定。表示这些类型的数据类型包含定点构造函数 (Mu
)、由最近的封闭 Mu-bound 项替换 (Var
) 以及零和一个参数类型运算符 (Nullary
和Unary
,分别)。
为了确保某些类型的格式正确,它们会作为三个 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)
你不是要在 a1
和 a2
上调用 subst
吗?
我正在尝试实现一个玩具常规类型系统,以确保一些良好的形式侧约束并允许在其中展开 mu 绑定。表示这些类型的数据类型包含定点构造函数 (Mu
)、由最近的封闭 Mu-bound 项替换 (Var
) 以及零和一个参数类型运算符 (Nullary
和Unary
,分别)。
为了确保某些类型的格式正确,它们会作为三个 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)
你不是要在 a1
和 a2
上调用 subst
吗?