将列表转换为具有类型约束的固定长度列表
Convert a list to list with type-constrained fixed length
让我定义一个长度受限的列表。即
data List (n::Nat) a where
Nil :: List 0 a
Cons :: a -> List (n-1) a -> List n a
然后我想从普通列表(例如任意长度的输入字符串)初始化这个列表。我可以这样做吗?是否可以这样写函数(或class)?
toConsList :: [a] -> List n a
或者这是否只适用于编译时已知长度的结构?
你不能,因为那需要依赖类型。结果 List
的 类型 取决于 值 。正如您的类型错误所示,您不能使用 foldr Cons Nil
(这将是显而易见的实现)来创建列表,因为累加器必须在整个折叠过程中保持相同的类型。
正如@chi 在评论中指出的那样,您可以使用存在的包装器来忽略类型参数以允许它工作。对于 一些未知的 n
,你最终会得到一个 List n a
的值,这比使用 [a]
.[=19= 没有任何好处]
有 Data.Vector.Fixed.fromList
,但是那里的文档告诉我们它 "Will throw error if list is shorter than resulting vector." 这意味着它实际上只是要求您在编译时指定向量(列表)的类型(长度)时间,如果未满足该期望,则在运行时截断或抛出错误。
您可能对伊德里斯的 Data.Vect.Vect
.
感兴趣
让我定义一个长度受限的列表。即
data List (n::Nat) a where
Nil :: List 0 a
Cons :: a -> List (n-1) a -> List n a
然后我想从普通列表(例如任意长度的输入字符串)初始化这个列表。我可以这样做吗?是否可以这样写函数(或class)?
toConsList :: [a] -> List n a
或者这是否只适用于编译时已知长度的结构?
你不能,因为那需要依赖类型。结果 List
的 类型 取决于 值 。正如您的类型错误所示,您不能使用 foldr Cons Nil
(这将是显而易见的实现)来创建列表,因为累加器必须在整个折叠过程中保持相同的类型。
正如@chi 在评论中指出的那样,您可以使用存在的包装器来忽略类型参数以允许它工作。对于 一些未知的 n
,你最终会得到一个 List n a
的值,这比使用 [a]
.[=19= 没有任何好处]
有 Data.Vector.Fixed.fromList
,但是那里的文档告诉我们它 "Will throw error if list is shorter than resulting vector." 这意味着它实际上只是要求您在编译时指定向量(列表)的类型(长度)时间,如果未满足该期望,则在运行时截断或抛出错误。
您可能对伊德里斯的 Data.Vect.Vect
.