    {-# 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' (\c :: Int
    c _ -> Int
    cInt -> Int -> Int
    forall a. Additive a => a -> a -> a
    +1) 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 (_:_) = 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 (i :: n
    i:is :: [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 (x :: t
    x:xs :: [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 l :: [a]
    l =  [a] -> [a] -> [a]
    forall a. [a] -> [a] -> [a]
    go [a]
    l []
      where
        go :: [a] -> [a] -> [a]
    go []     acc :: [a]
    acc = [a]
    acc
        go (x :: a
    x:xs :: [a]
    xs) acc :: [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
    !! _  = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error "invalid offset for !!"
    (x :: a
    x:_) !! 0  = a
    x
    (_:xs :: [a]
    xs) !! i :: 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