{-# LANGUAGE CPP #-}
module Basement.Compat.ExtList
    ( length
    , null
    , sum
    , reverse
    , (!!)
    ) where

import Basement.Compat.Base
import Basement.Numerical.Additive
import Basement.Types.OffsetSize
import qualified GHC.List as List

-- | Compute the size of the list
length :: [a] -> CountOf a
#if MIN_VERSION_base(4,8,0)
length :: [a] -> CountOf a
length = Int -> CountOf a
forall ty. Int -> CountOf ty
CountOf (Int -> CountOf a) -> ([a] -> Int) -> [a] -> CountOf a
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Int -> a -> Int) -> Int -> [a] -> Int
forall a b. (b -> a -> b) -> b -> [a] -> b
List.foldl' (\Int
c a
_ -> Int
cInt -> Int -> Int
forall a. Additive a => a -> a -> a
+Int
1) Int
0
#else
length = CountOf . loop 0
  where loop !acc []     = acc
        loop !acc (_:xs) = loop (1+acc) xs
#endif

null :: [a] -> Bool
null :: [a] -> Bool
null []    = Bool
True
null (a
_:[a]
_) = Bool
False

-- | Sum the element in a list
sum :: Additive n => [n] -> n
sum :: [n] -> n
sum []     = n
forall a. Additive a => a
azero
sum (n
i:[n]
is) = n -> [n] -> n
forall t. Additive t => t -> [t] -> t
loop n
i [n]
is
  where
    loop :: t -> [t] -> t
loop !t
acc [] = t
acc
    loop !t
acc (t
x:[t]
xs) = t -> [t] -> t
loop (t
acct -> t -> t
forall a. Additive a => a -> a -> a
+t
x) [t]
xs
    {-# INLINE loop #-}

reverse :: [a] -> [a]
reverse :: [a] -> [a]
reverse [a]
l =  [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
go [a]
l []
  where
    go :: [a] -> [a] -> [a]
go []     [a]
acc = [a]
acc
    go (a
x:[a]
xs) [a]
acc = [a] -> [a] -> [a]
go [a]
xs (a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
acc)

(!!) :: [a] -> Offset a -> a
[]    !! :: [a] -> Offset a -> a
!! Offset a
_  = [Char] -> a
forall a. HasCallStack => [Char] -> a
error [Char]
"invalid offset for !!"
(a
x:[a]
_) !! Offset a
0  = a
x
(a
_:[a]
xs) !! Offset a
i = [a]
xs [a] -> Offset a -> a
forall a. [a] -> Offset a -> a
!! Offset a -> Offset a
forall a. Enum a => a -> a
pred Offset a
i