为模糊的标题道歉,这里有一些上下文:http ://themonadreader.files.wordpress.com/2013/08/issue221.pdf
上一期的 GADTs 文章介绍了 Nat 类型和 NatSing 类型,用于各种类型级别的列表函数(concat、!!、head、repeat 等)。对于其中一些函数,有必要创建类型族以在 Nat 类型上定义 + 和 <。
data Nat = Zero | Succ Nat
data NatSing (n :: Nat) where
ZeroSing :: NatSing Zero
SuccSing :: NatSing n -> NatSing (Succ n)
data List (n :: Nat) a where
Nil :: List n a
Cons :: a -> List n a -> List (Succ n) a
无论如何,为了方便调用者,我编写了一个函数“list”,它将普通[a]
转换为 。List n a
这需要列表的长度作为输入,就像repeat
(来自链接的文章):
list :: [a] -> NatSing n -> List n a
list [] ZeroSing = Nil
list (x:xs) (SuccSing n) = Cons x (list xs n)
list _ _ = error "length mismatch"
使用辅助函数会很好toNatSing :: Int -> NatSing n
,所以上面可以写成
list :: [a] -> List n a
list xs = list' xs (toNatSing $ length xs)
where
list' :: [a] -> NatSing n -> List n a
list' = ... -- same as before, but this time I simply "know" the function is no longer partial
是否可以编写这样的函数toNatSing
?我一直在与类型搏斗,但还没有想出任何东西。
非常感谢!