我正在尝试编写函数
fromList :: [e] -> Vector n e
fromList [] = Nil
fromList (x:xs) = x :| fromList xs
使用矢量的这个定义
data Natural where
Zero :: Natural
Succ :: Natural -> Natural
data Vector n e where
Nil :: Vector Zero e
(:|) :: e -> Vector n e -> Vector (Succ n) e
infixr :|
然而,Haskell正在给出错误
Couldn't match type 'Zero with 'Succ n0
Expected type: Vector n e
Actual type: Vector ('Succ n0) e
In the expression: x :| fromList xs
In an equation for `fromList': fromList (x : xs) = x :| fromList xs
Failed, modules loaded: none.
我认为由于(:|)
的类型签名而引发错误。
有没有办法解决这个错误?
答案 0 :(得分:5)
错误是您的类型签名在n
中普遍量化,即它表示“对于任何n
,我们可以构建一个长度为{{1}的向量”从列表中“。与此不同,函数定义指出向量始终具有给定列表的长度。
基本上,你需要存在量化来定义这个函数(“根据列表长度,会有一个n
,n
是结果的长度向量”)。仅在昨天讨论you can't have existentially-quantified type variables in a signature。你可以拥有的是存在类型 - 最好再写为GADT,
n
然后你可以定义
data DynVector e where
DynVector :: Vector n e -> DynVector e