{-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeInType #-} module VecSpec where import Data.Kind import Data.Singletons import PeanoSpec (appendVec) import PeanoTypes import Test.Hspec main :: IO () main = hspec spec spec :: Spec spec = parallel $ do describe "concatVec" $ do it "concats a Vec of Vecs" $ do concatVec ((False `VCons` True `VCons` False `VCons` VNil) `VCons` (True `VCons` False `VCons` True `VCons` VNil) `VCons` VNil) `shouldBe` (False `VCons` True `VCons` False `VCons` True `VCons` False `VCons` True `VCons` VNil) ----- concatVec :: forall (e :: Type) (n :: Peano) (j :: Peano). (SingKind e, SingI j, e ~ Demote e) => Vec (Vec e j) n -> Vec e (Times n j) concatVec l = withSomeSing l $ \(singL :: Sing l) -> elimVecTyFun @(Vec e j) @n @(WhyConcatVecSym e j) @l singL base step where base :: WhyConcatVec e j Z VNil base = VNil step :: forall (k :: Peano) (x :: Vec e j) (xs :: Vec (Vec e j) k). Sing x -> Sing xs -> WhyConcatVec e j k xs -> WhyConcatVec e j (S k) (VCons x xs) step h _ vKJ = appendVec (fromSing h) vKJ