我在ghc 7.6中乱搞了数据线,并且它的运行方式并不像我认为的那样。
{-# LANGUAGE DataKinds, KindSignatures, TypeOperators #-}
import GHC.TypeLits
data Array (i :: Nat) a = Array {
num :: Int,
elems :: [a]
} deriving (Eq, Show)
arr10 :: Array 10 Int
arr10 = arrn 10
arr20 :: Array 20 Int
arr20 = arrn 20
arrn :: Int -> Array a Int
arrn n = Array n (replicate n 0)
arrconcat :: Array a e -> Array b e -> Array (a+b) e
arrconcat (Array a as) (Array b bs) = Array (a+b) (as ++ bs)
在ghci:
*Main> arr10
Array {num = 10, elems = [0,0,0,0,0,0,0,0,0,0]}
*Main> arr10 == arr10
True
*Main> arr20
Array {num = 20, elems = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}
*Main> arr10 `arrconcat` arr20
Array {num = 30, elems = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]}
*Main> :t arr10 `arrconcat` arr20
arr10 `arrconcat` arr20 :: Array (10 + 20) Int
*Main> :t arr10 `arrconcat` arr10 == arr20
<interactive>:1:1:
Couldn't match type `10 + 10' with `20'
Expected type: Array 20 Int
Actual type: Array (10 + 10) Int
In the first argument of `(==)', namely `arr10 `arrconcat` arr10'
In the expression: arr10 `arrconcat` arr10 == arr20
有没有办法做我正在尝试使用这种类型级数字或者计划最终工作?
答案 0 :(得分:0)
如果您定义类型级别的Peano数字,类型系列和数据种类实际上足以实现此功能:
{-# LANGUAGE DataKinds, TypeFamilies #-}
data Array (i :: Nat) a = Array {
num :: Int,
elems :: [a]
} deriving (Eq, Show)
arrn :: Int -> Array a Int
arrn n = Array n (replicate n 0)
data Nat = Zero | Succ Nat
type family Add (n :: Nat) (m :: Nat) :: Nat
type instance Add Zero m = m
type instance Add (Succ n) m = Succ (Add n m)
type Ten = Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))))))
type Twenty = Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ (Succ Zero)))))))))))))))))))
arr10 :: Array Ten Int
arr10 = arrn 10
arr20 :: Array Twenty Int
arr20 = arrn 20
arrconcat :: Array a e -> Array b e -> Array (Add a b) e
arrconcat (Array a as) (Array b bs) = Array (a+b) (as ++ bs)
这可以按照您的预期运作:
*Main> :t arr10 `arrconcat` arr10 == arr20
arr10 `arrconcat` arr10 == arr20 :: Bool
*Main> arr10 `arrconcat` arr10 == arr20
True
不幸的是,TypeLits
目前有点未煮熟。但正如Nathan Howell已经评论过的那样,他们正在努力,并且应该在GHC 7.8中做得更好。它会很棒!