假设我有以下
data Expr : Type -> Type where
Lift : a -> Expr a
Add : Num a => Expr a -> Expr a -> Expr a
Cnst : Expr a -> Expr b -> Expr a
data Context : Type -> Type where
Root : Context ()
L : Expr w -> Context x -> Expr y -> Expr z -> Context w
R : Expr w -> Context x -> Expr y -> Expr z -> Context w
M : Expr w -> Context x -> Expr y -> Expr z -> Context w
data Zipper : Type -> Type -> Type where
Z : Expr f -> Context g -> Zipper f g
E : String -> Context g -> Zipper String ()
如果我在表达式树中上升一级,我想编写一个重建Zipper的函数。类似的东西:
total
ZipUp : Zipper focus parent -> Type
ZipUp (Z e (R (Cnst {a} e1 e2) {x} c t u)) = Zipper a x
ZipUp (Z {f} e (L (Cnst l r) {x} c t u)) = Zipper f x
ZipUp (Z e (R (Add {a} e1 e2) {x} c t u)) = Zipper a x
ZipUp (Z {f} e (L (Add e1 e2) {x} c t u)) = Zipper f x
ZipUp _ = Zipper String ()
当我想编写函数以返回ZipUp
up : (x : Zipper focus parent) -> ZipUp x
up (Z e (R (Cnst l r) c x y)) = Z (Cnst l e) c
up (Z e (L (Cnst l r) c x y)) = Z (Cnst e r) c
up (Z e (R (Add l r) c x y)) = Z (Add l e) c
up (Z e (L (Add l r) c x y)) = Z (Add e r) c
up (Z e (R (Lift x) c l r)) = E "Some error" c
up (Z e (L (Lift x) c l r)) = E "Some error" c
up (E s c) = E s c
这无法对Add
案例进行类型检查,因为它无法推断focus (type of e)
与parent (expected type)
匹配
所以我的问题有两部分。
我可以做些什么来表达这种关系?
(如果Zipper是R
构建的,e
与[{1}}的类型相同,或r
的类型与e
相同在l
构造的案例中。我已尝试使用L
及其他变种,但无济于事。)
代码类型检查并运行,如果我注释掉最后一行{e = l}
以完成:
up
但是up : (x : Zipper focus parent) -> ZipUp x
up (Z e (R (Cnst l r) c x y)) = Z (Cnst l e) c
up (Z e (L (Cnst l r) c x y)) = Z (Cnst e r) c
案例中对类型的实际操作应该是相同的,但这不能进行类型检查,为什么会这样?
感谢您花时间阅读和/或回答!
答案 0 :(得分:1)
这无法对添加案例进行类型检查,因为它无法推断
focus (type of e)
与parent (expected type)
匹配
因为情况并非总是如此,例如
*main> :t Z (Lift "a") (R (Add (Lift 1) (Lift 2)) Root (Lift 4) (Lift 8))
Z (Lift "a") (R (Add (Lift 1) (Lift 2)) Root (Lift 4) (Lift 8)) : Zipper String Integer
由于Add (Lift 1) (Lift "a")
约束,Num a
不起作用。
我可以做些什么来表达这种关系?
如果您想在内容中表达关系:您有e : Expr f
并且可以说在f
案例中应该使用相同的Add
:
up (Z {f} e (R (Add l r {a=f}) c x y)) = Z (Add l e) c
up (Z {f} e (L (Add l r {a=f}) c x y)) = Z (Add e r) c
up (Z e (R (Add l r) c x y)) = ?whattodo_1
up (Z e (L (Add l r) c x y)) = ?whattodo_2
由于a != f
的情况,现在你有一个非全部功能。我不太想你做什么,所以我不能提供选择。 : - )
如果你想在Zipper
中表达关系,你可以(非常粗略地)表达:
data Context : Bool -> Type -> Type where
Root : Context False ()
L : Expr w -> Context b x -> Expr y -> Expr z -> Context False w
R : Expr w -> Context b x -> Expr y -> Expr z -> Context True w
M : Expr w -> Context b x -> Expr y -> Expr z -> Context False w
data Zipper : Type -> Type -> Type where
Z : Expr f -> Context False g -> Zipper f g
ZR : Expr f -> Context True f -> Zipper f f
E : String -> Context b g -> Zipper String ()
现在,您可以在R-Context中构建f = g
拉链时构建证明。同样,我不能具体,但我希望它在某种程度上有所帮助。