{-# LANGUAGE RebindableSyntax #-} {- | Functions that are counterparts of the @generic@ functions in "Data.List" using NumericPrelude.Numeric type classes. For input arguments we use the restrictive @ToInteger@ constraint, although in principle @RealRing@ would be enough. However we think that @take 0.5 xs@ is rather a bug than a feature, thus we forbid fractional types. On the other hand fractional types as result can be quite handy, e.g. in @average xs = sum xs / length xs@. -} module NumericPrelude.List.Generic ((!!), lengthLeft, lengthRight, replicate, take, drop, splitAt, findIndex, elemIndex, findIndices, elemIndices, ) where import NumericPrelude.List.Checked ((!!), ) import qualified Algebra.ToInteger as ToInteger import qualified Algebra.Ring as Ring import Algebra.Ring (one, ) import Algebra.Additive (zero, (+), (-), ) import qualified Data.Maybe as Maybe import Data.Tuple.HT (mapFst, ) import NumericPrelude.Base as List hiding (take, drop, splitAt, length, replicate, (!!), ) replicate :: (ToInteger.C n) => n -> a -> [a] replicate :: n -> a -> [a] replicate n n a x = n -> [a] -> [a] forall n a. C n => n -> [a] -> [a] take n n (a -> [a] forall a. a -> [a] List.repeat a x) take :: (ToInteger.C n) => n -> [a] -> [a] take :: n -> [a] -> [a] take n _ [] = [] take n n (a x:[a] xs) = if n nn -> n -> Bool forall a. Ord a => a -> a -> Bool <=n forall a. C a => a zero then [] else a x a -> [a] -> [a] forall a. a -> [a] -> [a] : n -> [a] -> [a] forall n a. C n => n -> [a] -> [a] take (n nn -> n -> n forall a. C a => a -> a -> a -n forall a. C a => a one) [a] xs drop :: (ToInteger.C n) => n -> [a] -> [a] drop :: n -> [a] -> [a] drop n _ [] = [] drop n n xt :: [a] xt@(a _:[a] xs) = if n nn -> n -> Bool forall a. Ord a => a -> a -> Bool <=n forall a. C a => a zero then [a] xt else n -> [a] -> [a] forall n a. C n => n -> [a] -> [a] drop (n nn -> n -> n forall a. C a => a -> a -> a -n forall a. C a => a one) [a] xs splitAt :: (ToInteger.C n) => n -> [a] -> ([a], [a]) splitAt :: n -> [a] -> ([a], [a]) splitAt n _ [] = ([], []) splitAt n n xt :: [a] xt@(a x:[a] xs) = if n nn -> n -> Bool forall a. Ord a => a -> a -> Bool <=n forall a. C a => a zero then ([], [a] xt) else ([a] -> [a]) -> ([a], [a]) -> ([a], [a]) forall a c b. (a -> c) -> (a, b) -> (c, b) mapFst (a xa -> [a] -> [a] forall a. a -> [a] -> [a] :) (([a], [a]) -> ([a], [a])) -> ([a], [a]) -> ([a], [a]) forall a b. (a -> b) -> a -> b $ n -> [a] -> ([a], [a]) forall n a. C n => n -> [a] -> ([a], [a]) splitAt (n nn -> n -> n forall a. C a => a -> a -> a -n forall a. C a => a one) [a] xs {- | Left associative length computation that is appropriate for types like @Integer@. -} lengthLeft :: (Ring.C n) => [a] -> n lengthLeft :: [a] -> n lengthLeft = (n -> a -> n) -> n -> [a] -> n forall (t :: * -> *) b a. Foldable t => (b -> a -> b) -> b -> t a -> b List.foldl (\n n a _ -> n nn -> n -> n forall a. C a => a -> a -> a +n forall a. C a => a one) n forall a. C a => a zero {- | Right associative length computation that is appropriate for types like @Peano@ number. -} lengthRight :: (Ring.C n) => [a] -> n lengthRight :: [a] -> n lengthRight = (a -> n -> n) -> n -> [a] -> n forall (t :: * -> *) a b. Foldable t => (a -> b -> b) -> b -> t a -> b List.foldr (\a _ n n -> n forall a. C a => a onen -> n -> n forall a. C a => a -> a -> a +n n) n forall a. C a => a zero elemIndex :: (Ring.C n, Eq a) => a -> [a] -> Maybe n elemIndex :: a -> [a] -> Maybe n elemIndex a e = (a -> Bool) -> [a] -> Maybe n forall n a. C n => (a -> Bool) -> [a] -> Maybe n findIndex (a ea -> a -> Bool forall a. Eq a => a -> a -> Bool ==) elemIndices :: (Ring.C n, Eq a) => a -> [a] -> [n] elemIndices :: a -> [a] -> [n] elemIndices a e = (a -> Bool) -> [a] -> [n] forall n a. C n => (a -> Bool) -> [a] -> [n] findIndices (a ea -> a -> Bool forall a. Eq a => a -> a -> Bool ==) findIndex :: Ring.C n => (a -> Bool) -> [a] -> Maybe n findIndex :: (a -> Bool) -> [a] -> Maybe n findIndex a -> Bool p = [n] -> Maybe n forall a. [a] -> Maybe a Maybe.listToMaybe ([n] -> Maybe n) -> ([a] -> [n]) -> [a] -> Maybe n forall b c a. (b -> c) -> (a -> b) -> a -> c . (a -> Bool) -> [a] -> [n] forall n a. C n => (a -> Bool) -> [a] -> [n] findIndices a -> Bool p findIndices :: Ring.C n => (a -> Bool) -> [a] -> [n] findIndices :: (a -> Bool) -> [a] -> [n] findIndices a -> Bool p = ((n, a) -> n) -> [(n, a)] -> [n] forall a b. (a -> b) -> [a] -> [b] map (n, a) -> n forall a b. (a, b) -> a fst ([(n, a)] -> [n]) -> ([a] -> [(n, a)]) -> [a] -> [n] forall b c a. (b -> c) -> (a -> b) -> a -> c . ((n, a) -> Bool) -> [(n, a)] -> [(n, a)] forall a. (a -> Bool) -> [a] -> [a] filter (a -> Bool p (a -> Bool) -> ((n, a) -> a) -> (n, a) -> Bool forall b c a. (b -> c) -> (a -> b) -> a -> c . (n, a) -> a forall a b. (a, b) -> b snd) ([(n, a)] -> [(n, a)]) -> ([a] -> [(n, a)]) -> [a] -> [(n, a)] forall b c a. (b -> c) -> (a -> b) -> a -> c . [n] -> [a] -> [(n, a)] forall a b. [a] -> [b] -> [(a, b)] zip ((n -> n) -> n -> [n] forall a. (a -> a) -> a -> [a] iterate (n forall a. C a => a onen -> n -> n forall a. C a => a -> a -> a +) n forall a. C a => a zero)