antelude-0.1.0: src/Antelude/Array.hs
{- |
Module : Antelude.Array
Description : Contains some functions for Arrays, and reexports the Data.Array module.
Maintainer : dneavesdev@pm.me
-}
module Antelude.Array
( -- * Rexports
module ArrayExport
-- * New and Reconstructed for safety
, atIndex
, enumerate
, fromList
, fromNonEmpty
, map
, toList
, toNonEmpty
, update
) where
import safe Antelude.Bool ( and )
import safe Antelude.Function ( flip, (|>) )
import safe Antelude.Internal.TypesClasses
( Functor (fmap)
, List
, Maybe (..)
, NonEmpty
)
import safe qualified Antelude.List.NonEmpty as NE ( fromList, toList )
import safe Antelude.Tuple.Pair ( first, second )
import safe Data.Array as ArrayExport hiding
( assocs
, elems
, listArray
, (//)
, (!)
)
import safe qualified Data.Array as Array
import safe Prelude ( (<=), (>=) )
-- | This is here for parity with Data.List. The definition is just 'fmap' from 'Functor'.
map :: (e -> f) -> Array i e -> Array i f
map = fmap
-- | Convert a 'List' to an 'Array' along with a pair of bounds.
fromList :: (Array.Ix i) => (i, i) -> List a -> Array i a
fromList = Array.listArray
-- | Convert an 'Array' to a 'List'.
toList :: Array i e -> List e
toList = Array.elems
-- | Enumerate an 'Array' into a 'List' of indices i and elements e.
enumerate :: (Array.Ix i) => Array i e -> List (i, e)
enumerate = Array.assocs
-- | Convert a 'NonEmpty' to an 'Array' along with a pair of bounds.
fromNonEmpty :: (Array.Ix i) => (i, i) -> NonEmpty a -> Array i a
fromNonEmpty bound ne = NE.toList ne |> fromList bound
-- | Convert an 'Array' to a 'NonEmpty'.
toNonEmpty :: (Array.Ix i) => Array i a -> Maybe (NonEmpty a)
toNonEmpty arr = toList arr |> NE.fromList
-- | Reconstruct an 'Array' with the given 'List' of indices i and elements e in their designated positions.
update :: (Array.Ix i) => List (i, e) -> Array i e -> Array i e
update = flip (Array.//)
-- | Obtain the element at the given index. 'Nothing' if the index is not valid.
atIndex :: (Array.Ix i) => i -> Array i e -> Maybe e
atIndex idx arr =
if (idx >= first (Array.bounds arr)) `and` (idx <= second (Array.bounds arr))
then
(Array.!) arr idx |> Just
else
Nothing