让我定义一个约束长度的列表。即。
data List (n::Nat) a where
Nil :: List 0 a
Cons :: a -> List (n-1) a -> List n a
然后我想从公共列表中初始化此列表(例如,任意长度的输入字符串)。我能这样做吗?是否有可能像这样编写函数(或类)?
toConsList :: [a] -> List n a
或者这仅适用于编译时已知长度的结构?
答案 0 :(得分:2)
你不能,因为这需要依赖类型。结果List
的类型取决于 值。正如您的类型错误所示,您无法使用foldr Cons Nil
(这将是明显的实现)来创建列表,因为累加器必须保持整个折叠的相同类型。
正如@chi在评论中指出的那样,您可以使用存在包装器来忽略类型参数以允许它工作。对于某些未知的 List n a
,您最终会得到n
的值,只需使用[a]
即可获得任何结果。
有Data.Vector.Fixed.fromList
,但那里的文档告诉我们,如果列表比结果向量短,它会抛出错误。"这意味着它实际上只是要求您在编译时指定向量(列表)的类型(长度),并在运行时截断或抛出错误(如果未满足该期望)。
您可能对Idris'感兴趣Data.Vect.Vect