【发布时间】:2012-01-06 15:19:24
【问题描述】:
我在我的程序中与存在类型作斗争。我想我正在尝试做一些非常合理的事情,但是我无法通过类型检查器:(
我有一个类似于 Monad 的数据类型
data M o = R o | forall o1. B (o1 -> M o) (M o1)
现在我为它创建一个上下文,类似于Haskell Wiki article on Zipper 中描述的内容,但是为了简单起见,我使用函数而不是数据结构 -
type C o1 o2 = M o1 -> M o2
现在,当我尝试编写一个将数据值拆分为其上下文和子值的函数时,类型检查器会抱怨 -
ctx :: M o -> (M o1 -> M o, M o1)
ctx (B f m) = (B f, m) -- Doesn't typecheck
错误是 -
Couldn't match type `o2' with `o1'
`o2' is a rigid type variable bound by
a pattern with constructor
B :: forall o o1. (o1 -> M o) -> M o1 -> M o,
in an equation for `ctx'
at delme1.hs:6:6
`o1' is a rigid type variable bound by
the type signature for ctx :: M o -> (M o1 -> M o, M o1)
at delme1.hs:6:1
Expected type: M o2
Actual type: M o1
In the expression: m
In the expression: (B f, m)
但是,我可以像这样解决它 -
ctx (B f m) = let (c,m') = ctx m in ((B f) . c, m') -- OK
为什么第二个定义类型检查而不是第一个?
另外,如果我尝试通过检查 R 将 ctx 转换为完整的函数,我再次收到类型检查错误 -
ctx (R o) = (id, R o) -- Doesn't typecheck
错误 -
Couldn't match type `o' with `o1'
`o' is a rigid type variable bound by
the type signature for ctx :: M o -> (M o1 -> M o, M o1)
at delme1.hs:7:1
`o1' is a rigid type variable bound by
the type signature for ctx :: M o -> (M o1 -> M o, M o1)
at delme1.hs:7:1
In the first argument of `R', namely `o'
In the expression: R o
In the expression: (id, R o)
如何解决此错误?
感谢任何帮助!
【问题讨论】:
标签: haskell typeerror typechecking existential-type zipper