{-# LANGUAGE StandaloneDeriving, DeriveGeneric #-}
module GHC.Data.SizedSeq
  ( SizedSeq(..)
  , emptySS
  , addToSS
  , addListToSS
  , ssElts
  , sizeSS
  ) where

import Prelude -- See note [Why do we import Prelude here?]
import Control.DeepSeq
import Data.Binary
import Data.List (genericLength)
import GHC.Generics

data SizedSeq a = SizedSeq {-# UNPACK #-} !Word [a]
  deriving (forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (SizedSeq a) x -> SizedSeq a
forall a x. SizedSeq a -> Rep (SizedSeq a) x
$cto :: forall a x. Rep (SizedSeq a) x -> SizedSeq a
$cfrom :: forall a x. SizedSeq a -> Rep (SizedSeq a) x
Generic, Int -> SizedSeq a -> ShowS
forall a. Show a => Int -> SizedSeq a -> ShowS
forall a. Show a => [SizedSeq a] -> ShowS
forall a. Show a => SizedSeq a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SizedSeq a] -> ShowS
$cshowList :: forall a. Show a => [SizedSeq a] -> ShowS
show :: SizedSeq a -> String
$cshow :: forall a. Show a => SizedSeq a -> String
showsPrec :: Int -> SizedSeq a -> ShowS
$cshowsPrec :: forall a. Show a => Int -> SizedSeq a -> ShowS
Show)

instance Functor SizedSeq where
  fmap :: forall a b. (a -> b) -> SizedSeq a -> SizedSeq b
fmap a -> b
f (SizedSeq Word
sz [a]
l) = forall a. Word -> [a] -> SizedSeq a
SizedSeq Word
sz (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f [a]
l)

instance Foldable SizedSeq where
  foldr :: forall a b. (a -> b -> b) -> b -> SizedSeq a -> b
foldr a -> b -> b
f b
c SizedSeq a
ss = forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr a -> b -> b
f b
c (forall a. SizedSeq a -> [a]
ssElts SizedSeq a
ss)

instance Traversable SizedSeq where
  traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> SizedSeq a -> f (SizedSeq b)
traverse a -> f b
f (SizedSeq Word
sz [a]
l) = forall a. Word -> [a] -> SizedSeq a
SizedSeq Word
sz forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse a -> f b
f (forall a. [a] -> [a]
reverse [a]
l)

instance Binary a => Binary (SizedSeq a)

instance NFData a => NFData (SizedSeq a) where
  rnf :: SizedSeq a -> ()
rnf (SizedSeq Word
_ [a]
xs) = forall a. NFData a => a -> ()
rnf [a]
xs

emptySS :: SizedSeq a
emptySS :: forall a. SizedSeq a
emptySS = forall a. Word -> [a] -> SizedSeq a
SizedSeq Word
0 []

addToSS :: SizedSeq a -> a -> SizedSeq a
addToSS :: forall a. SizedSeq a -> a -> SizedSeq a
addToSS (SizedSeq Word
n [a]
r_xs) a
x = forall a. Word -> [a] -> SizedSeq a
SizedSeq (Word
nforall a. Num a => a -> a -> a
+Word
1) (a
xforall a. a -> [a] -> [a]
:[a]
r_xs)

addListToSS :: SizedSeq a -> [a] -> SizedSeq a
addListToSS :: forall a. SizedSeq a -> [a] -> SizedSeq a
addListToSS (SizedSeq Word
n [a]
r_xs) [a]
xs
  = forall a. Word -> [a] -> SizedSeq a
SizedSeq (Word
n forall a. Num a => a -> a -> a
+ forall i a. Num i => [a] -> i
genericLength [a]
xs) (forall a. [a] -> [a]
reverse [a]
xs forall a. [a] -> [a] -> [a]
++ [a]
r_xs)

ssElts :: SizedSeq a -> [a]
ssElts :: forall a. SizedSeq a -> [a]
ssElts (SizedSeq Word
_ [a]
r_xs) = forall a. [a] -> [a]
reverse [a]
r_xs

sizeSS :: SizedSeq a -> Word
sizeSS :: forall a. SizedSeq a -> Word
sizeSS (SizedSeq Word
n [a]
_) = Word
n