{-# LANGUAGE GADTs #-}
__module__ Problem1.Deep __where__
__import__ __qualified__ Prelude __as__ P
__import__ Prelude(Int,(+),(-),max,min,(<),(<=),(==),(&&),Bool,Show,String, (!!), otherwise, div)
__import__ __qualified__ Problem1.Shallow __as__ V
__import__ __qualified__ Problem1.Shallow_Instances ()
----------------
-- Problem 1(c)
__type__ Ix = P.Int
__type__ Length = P.Int
__type__ Vector = D
__data__ D a __where__
FromList :: [a] -> D a
FromV :: V.V a -> D a
(**:++**) :: D a -> D a -> D a
-- primitive
(++) :: D a -> D a -> D a
(++) = (**:++**)
length :: Vector a -> Length
length (xs **:++** ys) = length xs + length ys
length (FromList xs) = P.length xs
length (FromV v) = V.length v
drop :: Ix -> Vector a -> Vector a
drop i (xs **:++** ys) | i <= l = drop i xs **:++** ys
| otherwise = drop (i-l) ys
__where__ l = length xs
drop i (FromList xs) = FromList (P.drop i xs)
drop i (FromV v) = FromV (V.drop i v)
take :: Ix -> Vector a -> Vector a
take i (xs **:++** ys) | i <= l = take i xs
| otherwise = xs **:++** take (i-l) ys
__where__ l = length xs
take i (FromList xs) = FromList (P.take i xs)
take i (FromV v) = FromV (V.take i v)
-- Derived operations:
splitAt :: Ix -> Vector a -> (Vector a, Vector a)
splitAt i v = (take i v, drop i v)
-- --------------------------------------------------------------
-- For completeness (not asked for in exam question):
fromFun :: Length -> (Ix -> a) -> Vector a
fromFun l f = FromV (V.V l f)
fromList :: [a] -> Vector a
fromList = FromList
index :: Vector a -> Ix -> a
index (xs **:++** ys) i | i<l = index xs i
| otherwise = index ys (i-l)
__where__ l = length xs
index (FromList xs) i = xs P.!! i
index (FromV v) i = V.index v i
head :: Vector a -> a
head xs = index xs 0
tail :: Vector a -> Vector a
tail = drop 1
----------------------------------------------------------------
-- Not part of the exam question, but needed in pratice
toList :: Vector a -> [a]
toList (FromList xs) = xs
toList (FromV v) = V.toList v
toList (v **:++** w) = toList v P.++ toList w