{-# LANGUAGE StandaloneDeriving, ExistentialQuantification, ScopedTypeVariables, TemplateHaskell, TypeOperators, TypeFamilies #-} module Data.Param.Vector ( Vector , empty , (+>) , singleton , vectorTH , unsafeVector , readVector , length , lengthT , fromVector , null , (!) , replace , head , last , init , tail , take , drop , select , (<+) , (++) , map , zipWith , foldl , foldr , zip , unzip , shiftl , shiftr , rotl , rotr , concat , reverse , iterate , iteraten , generate , generaten , copy , copyn , split ) where import Types import Types.Data.Num import Types.Data.Num.Decimal.Literals.TH import Data.Param.Index import Data.Typeable import qualified Prelude as P import Prelude hiding ( null, length, head, tail, last, init, take, drop, (++), map, foldl, foldr, zipWith, zip, unzip, concat, reverse, iterate ) import qualified Data.Foldable as DF (Foldable, foldr) import qualified Data.Traversable as DT (Traversable(traverse)) import Language.Haskell.TH hiding (Pred) import Language.Haskell.TH.Syntax (Lift(..)) newtype (NaturalT s) => Vector s a = Vector {unVec :: [a]} deriving Eq -- deriving instance (NaturalT s, Typeable s, Data s, Typeable a, Data a) => Data (TFVec s a) -- ========================== -- = Constructing functions = -- ========================== empty :: Vector D0 a empty = Vector [] (+>) :: a -> Vector s a -> Vector (Succ s) a x +> (Vector xs) = Vector (x:xs) infix 5 +> singleton :: a -> Vector D1 a singleton x = x +> empty -- FIXME: Not the most elegant solution... but it works for now in clash vectorTH :: (Lift a) => [a] -> ExpQ -- vectorTH xs = sigE [| (TFVec xs) |] (decTFVecT (toInteger (P.length xs)) xs) vectorTH [] = [| empty |] vectorTH [x] = [| singleton x |] vectorTH (x:xs) = [| x +> $(vectorTH xs) |] unsafeVector :: NaturalT s => s -> [a] -> Vector s a unsafeVector l xs | fromIntegerT l /= P.length xs = error (show 'unsafeVector P.++ ": dynamic/static lenght mismatch") | otherwise = Vector xs readVector :: (Read a, NaturalT s) => String -> Vector s a readVector = read -- ======================= -- = Observing functions = -- ======================= length :: forall s a . NaturalT s => Vector s a -> Int length _ = fromIntegerT (undefined :: s) lengthT :: NaturalT s => Vector s a -> s lengthT = undefined fromVector :: NaturalT s => Vector s a -> [a] fromVector (Vector xs) = xs null :: Vector D0 a -> Bool null _ = True (!) :: ( PositiveT s , NaturalT u , (s :>: u) ~ True) => Vector s a -> Index u -> a (Vector xs) ! i = xs !! (fromInteger (toInteger i)) -- ========================== -- = Transforming functions = -- ========================== replace :: (PositiveT s, NaturalT u, (s :>: u) ~ True) => Vector s a -> Index u -> a -> Vector s a replace (Vector xs) i y = Vector $ replace' xs (toInteger i) y where replace' [] _ _ = [] replace' (_:xs) 0 y = (y:xs) replace' (x:xs) n y = x : (replace' xs (n-1) y) head :: PositiveT s => Vector s a -> a head = P.head . unVec tail :: PositiveT s => Vector s a -> Vector (Pred s) a tail = liftV P.tail last :: PositiveT s => Vector s a -> a last = P.last . unVec init :: PositiveT s => Vector s a -> Vector (Pred s) a init = liftV P.init take :: NaturalT i => i -> Vector s a -> Vector (Min s i) a take i = liftV $ P.take (fromIntegerT i) drop :: NaturalT i => i -> Vector s a -> Vector (s :-: (Min s i)) a drop i = liftV $ P.drop (fromIntegerT i) select :: (NaturalT f, NaturalT s, NaturalT n, (f :<: i) ~ True, (((s :*: n) :+: f) :<=: i) ~ True) => f -> s -> n -> Vector i a -> Vector n a select f s n = liftV (select' f' s' n') where (f', s', n') = (fromIntegerT f, fromIntegerT s, fromIntegerT n) select' f s n = ((selectFirst0 s n).(P.drop f)) selectFirst0 :: Int -> Int -> [a] -> [a] selectFirst0 s n l@(x:_) | n > 0 = x : selectFirst0 s (n-1) (P.drop s l) | otherwise = [] selectFirst0 _ 0 [] = [] (<+) :: Vector s a -> a -> Vector (Succ s) a (<+) (Vector xs) x = Vector (xs P.++ [x]) (++) :: Vector s a -> Vector s2 a -> Vector (s :+: s2) a (++) = liftV2 (P.++) infixl 5 <+ infixr 5 ++ map :: (a -> b) -> Vector s a -> Vector s b map f = liftV (P.map f) zipWith :: (a -> b -> c) -> Vector s a -> Vector s b -> Vector s c zipWith f = liftV2 (P.zipWith f) foldl :: (a -> b -> a) -> a -> Vector s b -> a foldl f e = (P.foldl f e) . unVec foldr :: (b -> a -> a) -> a -> Vector s b -> a foldr f e = (P.foldr f e) . unVec zip :: Vector s a -> Vector s b -> Vector s (a, b) zip = liftV2 P.zip unzip :: Vector s (a, b) -> (Vector s a, Vector s b) unzip (Vector xs) = let (a,b) = P.unzip xs in (Vector a, Vector b) shiftl :: (PositiveT s, NaturalT n, n ~ Pred s, s ~ Succ n) => Vector s a -> a -> Vector s a shiftl xs x = x +> init xs shiftr :: (PositiveT s, NaturalT n, n ~ Pred s, s ~ Succ n) => Vector s a -> a -> Vector s a shiftr xs x = tail xs <+ x rotl :: forall s a . NaturalT s => Vector s a -> Vector s a rotl = liftV rotl' where vlen = fromIntegerT (undefined :: s) rotl' [] = [] rotl' xs = let (i,[l]) = splitAt (vlen - 1) xs in l : i rotr :: NaturalT s => Vector s a -> Vector s a rotr = liftV rotr' where rotr' [] = [] rotr' (x:xs) = xs P.++ [x] concat :: Vector s1 (Vector s2 a) -> Vector (s1 :*: s2) a concat = liftV (P.foldr ((P.++).unVec) []) reverse :: Vector s a -> Vector s a reverse = liftV P.reverse iterate :: NaturalT s => (a -> a) -> a -> Vector s a iterate = iteraten (undefined :: s) iteraten :: NaturalT s => s -> (a -> a) -> a -> Vector s a iteraten s f x = let s' = fromIntegerT s in Vector (P.take s' $ P.iterate f x) generate :: NaturalT s => (a -> a) -> a -> Vector s a generate = generaten (undefined :: s) generaten :: NaturalT s => s -> (a -> a) -> a -> Vector s a generaten s f x = let s' = fromIntegerT s in Vector (P.take s' $ P.tail $ P.iterate f x) copy :: NaturalT s => a -> Vector s a copy x = copyn (undefined :: s) x copyn :: NaturalT s => s -> a -> Vector s a copyn s x = iteraten s id x split :: ( NaturalT s -- , IsEven s ~ True ) => Vector s a -> (Vector (Div2 s) a, Vector (Div2 s) a) split (Vector xs) = (Vector (P.take vlen xs), Vector (P.drop vlen xs)) where vlen = round ((fromIntegral (P.length xs)) / 2) -- ============= -- = Instances = -- ============= instance Show a => Show (Vector s a) where showsPrec _ = showV.unVec where showV [] = showString "<>" showV (x:xs) = showChar '<' . shows x . showl xs where showl [] = showChar '>' showl (x:xs) = showChar ',' . shows x . showl xs instance (Read a, NaturalT nT) => Read (Vector nT a) where readsPrec _ str | all fitsLength possibilities = P.map toReadS possibilities | otherwise = error (fName P.++ ": string/dynamic length mismatch") where fName = "Data.Param.TFVec.read" expectedL = fromIntegerT (undefined :: nT) possibilities = readVectorList str fitsLength (_, l, _) = l == expectedL toReadS (xs, _, rest) = (Vector xs, rest) instance NaturalT s => DF.Foldable (Vector s) where foldr = foldr instance NaturalT s => Functor (Vector s) where fmap = map instance NaturalT s => DT.Traversable (Vector s) where traverse f = (fmap Vector).(DT.traverse f).unVec instance (Lift a, NaturalT nT) => Lift (Vector nT a) where lift (Vector xs) = [| unsafeVectorCoerse $(decLiteralV (fromIntegerT (undefined :: nT))) (Vector xs) |] -- ====================== -- = Internal Functions = -- ====================== liftV :: ([a] -> [b]) -> Vector nT a -> Vector nT' b liftV f = Vector . f . unVec liftV2 :: ([a] -> [b] -> [c]) -> Vector s a -> Vector s2 b -> Vector s3 c liftV2 f a b = Vector (f (unVec a) (unVec b)) splitAtM :: Int -> [a] -> Maybe ([a],[a]) splitAtM n xs = splitAtM' n [] xs where splitAtM' 0 xs ys = Just (xs, ys) splitAtM' n xs (y:ys) | n > 0 = do (ls, rs) <- splitAtM' (n-1) xs ys return (y:ls,rs) splitAtM' _ _ _ = Nothing unsafeVectorCoerse :: nT' -> Vector nT a -> Vector nT' a unsafeVectorCoerse _ (Vector v) = (Vector v) readVectorList :: Read a => String -> [([a], Int, String)] readVectorList = readParen' False (\r -> [pr | ("<",s) <- lexVector r, pr <- readl s]) where readl s = [([],0,t) | (">",t) <- lexVector s] P.++ [(x:xs,1+n,u) | (x,t) <- reads s, (xs, n, u) <- readl' t] readl' s = [([],0,t) | (">",t) <- lexVector s] P.++ [(x:xs,1+n,v) | (",",t) <- lex s, (x,u) <- reads t, (xs,n,v) <- readl' u] readParen' b g = if b then mandatory else optional where optional r = g r P.++ mandatory r mandatory r = [(x,n,u) | ("(",s) <- lexVector r, (x,n,t) <- optional s, (")",u) <- lexVector t] -- Custom lexer for FSVecs, we cannot use lex directly because it considers -- sequences of < and > as unique lexemes, and that breaks nested FSVecs, e.g. -- <<1,2><3,4>> lexVector :: ReadS String lexVector ('>':rest) = [(">",rest)] lexVector ('<':rest) = [("<",rest)] lexVector str = lex str