{- |
Module      : Antelude.List.NonEmpty
Description : Contains some functions for NonEmptys, and reexports the Data.List.NonEmpty module.
Maintainer  : dneavesdev@pm.me
-}
module Antelude.List.NonEmpty
    ( -- * Rexports
      module NEExport
      -- * New and Reconstructed for safety
    , append
    , appendList
    , atIndex
    , fromList
    , prepend
    ) where

import safe           Antelude.Function              ( flip, (|>) )
import safe           Antelude.Internal.TypesClasses
    ( Int
    , List
    , Maybe (..)
    , Ordering (..)
    )
import safe           Antelude.List                  as AL ( head )

import safe           Data.List.NonEmpty             as NEExport hiding
    ( append
    , appendList
    , fromList
    )
import safe qualified Data.List.NonEmpty             as NE

import safe           Prelude                        ( Ord (compare) )


-- | Obtain the element at the given index, starting at 0. 'Nothing' if the index is not valid.
atIndex :: Int -> NonEmpty a -> Maybe a
atIndex :: forall a. Int -> NonEmpty a -> Maybe a
atIndex Int
index NonEmpty a
lst = case Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Int
index Int
0 of
  Ordering
LT ->
    Maybe a
forall a. Maybe a
Nothing
  Ordering
_ ->
    NonEmpty a
lst
      NonEmpty a -> (NonEmpty a -> [a]) -> [a]
forall a b. a -> (a -> b) -> b
|> Int -> NonEmpty a -> [a]
forall a. Int -> NonEmpty a -> [a]
NE.drop
        Int
index
      [a] -> ([a] -> Maybe a) -> Maybe a
forall a b. a -> (a -> b) -> b
|> [a] -> Maybe a
forall a. List a -> Maybe a
AL.head


-- | Convert a `List a` to a `NonEmpty a`
fromList :: List a -> Maybe (NonEmpty a)
fromList :: forall a. List a -> Maybe (NonEmpty a)
fromList = [a] -> Maybe (NonEmpty a)
forall a. List a -> Maybe (NonEmpty a)
NE.nonEmpty

-- | Add an item to the beginning of a 'NonEmpty'.
prepend :: NonEmpty a -> NonEmpty a -> NonEmpty a
prepend :: forall a. NonEmpty a -> NonEmpty a -> NonEmpty a
prepend = (NonEmpty a -> NonEmpty a -> NonEmpty a)
-> NonEmpty a -> NonEmpty a -> NonEmpty a
forall a b c. (a -> b -> c) -> b -> a -> c
flip NonEmpty a -> NonEmpty a -> NonEmpty a
forall a. NonEmpty a -> NonEmpty a -> NonEmpty a
NE.append


-- | Add an item to the end of a 'NonEmpty'.
append :: NonEmpty a -> NonEmpty a -> NonEmpty a
append :: forall a. NonEmpty a -> NonEmpty a -> NonEmpty a
append = NonEmpty a -> NonEmpty a -> NonEmpty a
forall a. NonEmpty a -> NonEmpty a -> NonEmpty a
NE.append


-- | Add a 'List' to the end of a 'NonEmpty'.
appendList :: List a -> NonEmpty a -> NonEmpty a
appendList :: forall a. List a -> NonEmpty a -> NonEmpty a
appendList = (NonEmpty a -> List a -> NonEmpty a)
-> List a -> NonEmpty a -> NonEmpty a
forall a b c. (a -> b -> c) -> b -> a -> c
flip NonEmpty a -> List a -> NonEmpty a
forall a. NonEmpty a -> [a] -> NonEmpty a
NE.appendList