-- | Module of variadic functions. -- -- All types used are re-exported. -- {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} module Data.FoldApp.Function ( Alternative , Bool , FoldlApp , FoldrApp , IntMap , IntSet , Map , MonadPlus , Monoid , NonEmpty , Num , Ord , Ordering , Seq , Set , allOf , allOfBy , asumOf , dualAsumOf , dualFoldOf , dualMsumOf , firstOf , foldOf , intSetOf , lastOf , lazyIntMapOf , lazyMapOf , listOf , maxOf , maxOfBy , minOf , minOfBy , msumOf , nonEmptyOf , productOf , reverseNonEmptyOf , reverseOf , reverseSeqOf , seqOf , setOf , strictIntMapOf , strictMapOf , sumOf ) where import Control.Applicative ( Alternative(empty, (<|>)) ) -- import Control.Monad ( MonadPlus(mzero, mplus) ) -- import Data.Bool ( Bool(True, False) , (||) , (&&) ) -- import Data.FoldApp.Identity ( FoldlApp , FoldrApp , foldlApp , foldrApp ) -- import Data.IntMap (IntMap) import qualified Data.IntMap.Lazy as LazyIntMap import qualified Data.IntMap.Strict as StrictIntMap import Data.IntSet (IntSet) import qualified Data.IntSet as IntSet import Data.List.NonEmpty(NonEmpty((:|))) import qualified Data.List.NonEmpty as NonEmpty import Data.Map (Map) import qualified Data.Map.Lazy as LazyMap import qualified Data.Map.Strict as StrictMap import Data.Monoid ( Monoid(mempty, mappend) ) -- import Data.Ord ( Ord , Ordering(LT, EQ, GT) ) -- import Data.Sequence (Seq) import qualified Data.Sequence as Seq import Data.Set(Set) import qualified Data.Set as Set import Prelude ( Num((+), (*)) , (.) , flip , max , min , uncurry ) -- -- | True if all arguments are True, False otherwise. -- allOf :: FoldrApp Bool Bool f => f allOf = foldrApp (&&) True -- | True if all arguments map to True, False otherwise. -- allOfBy :: FoldlApp a Bool f => (a -> Bool) -> f allOfBy f = foldlApp (\a x -> a && f x) True -- | True if any arguments are True, False otherwise. -- anyOf :: FoldrApp Bool Bool f => f anyOf = foldrApp (||) False -- | True if any arguments map to True, False otherwise. -- anyOfBy :: FoldlApp a Bool f => (a -> Bool) -> f anyOfBy f = foldlApp (\a x -> a || f x) False -- | Concatentate all arguments with @\<|\>@. -- asumOf :: forall a f g. (Alternative f, FoldrApp (f a) (f a) g) => g asumOf = foldrApp (<|>) (empty :: f a) -- | Concatenate all arguments with @\<|\>@ in reverse order. -- dualAsumOf :: forall a f g. (Alternative f, FoldrApp (f a) (f a) g) => g dualAsumOf = foldrApp (flip (<|>)) (empty :: f a) -- | Concatenate all argments with @mappend@ in reverse order. -- dualFoldOf :: forall a f. (Monoid a, FoldlApp a a f) => f dualFoldOf = foldlApp (flip mappend) (mempty :: a) -- | Concatenate all arguments with @mplus@ in reverse order. -- dualMsumOf :: forall a m f. (MonadPlus m, FoldrApp (m a) (m a) f) => f dualMsumOf = foldrApp (flip mplus) (mzero :: m a) -- | Returns the first argument. -- firstOf :: forall a f. FoldlApp a a f => a -> f firstOf = foldlApp ((\x _ -> x) :: a -> a -> a) -- | Concatenate all arguments with @mappend@. -- foldOf :: forall a f. (Monoid a, FoldrApp a a f) => f foldOf = foldrApp mappend (mempty :: a) -- | Form an @IntSet@ from all arguments. -- intSetOf :: forall f. FoldlApp IntSet.Key IntSet f => f intSetOf = foldlApp (flip IntSet.insert) IntSet.empty -- | Returns the last argument. -- lastOf :: forall a f. FoldlApp a a f => a -> f lastOf = foldlApp (\_ y -> y) -- | Form a lazy @IntMap@ from all arguments. -- lazyIntMapOf :: forall a f. FoldlApp (StrictIntMap.Key, a) (IntMap a) f => f lazyIntMapOf = foldlApp (flip (uncurry LazyIntMap.insert)) (LazyIntMap.empty :: IntMap a) -- -- | Form a lazy @Map@ from all arguments. -- lazyMapOf :: forall k a f. (Ord k, FoldlApp (k, a) (Map k a) f) => f lazyMapOf = foldlApp (flip (uncurry LazyMap.insert)) (LazyMap.empty :: Map k a) -- -- | Form a list from all arguments. -- listOf :: forall a f. FoldrApp a [a] f => f listOf = foldrApp (:) ([] :: [a]) -- | Return the largest argument. -- maxOf :: forall a f. (Ord a, FoldlApp a a f) => a -> f maxOf = foldlApp max -- | Return the largest argument by the given comparator. -- maxOfBy :: forall a f. (Ord a, FoldlApp a a f) => (a -> a -> Ordering) -> a -> f maxOfBy f = foldlApp (\a x -> case f a x of GT -> a; _ -> x) -- | Return the smallest argument. -- minOf :: forall a f. (Ord a, FoldlApp a a f) => a -> f minOf = foldlApp min -- | Return the smallest argument by the given comparator. -- minOfBy :: forall a f. (Ord a, FoldlApp a a f) => (a -> a -> Ordering) -> a -> f minOfBy f = foldlApp (\a x -> case f a x of GT -> x; _ -> a) -- | Concatentate all arguments with @mplus@. -- msumOf :: forall a m f. (MonadPlus m, FoldrApp (m a) (m a) f) => f msumOf = foldrApp mplus (mzero :: m a) -- | Form a @NonEmpty@ list from all arguments. -- nonEmptyOf :: FoldrApp a (NonEmpty a) f => a -> f nonEmptyOf = foldrApp (\a (x:|xs) -> x:|(a:xs)) . (:|[]) -- | Return the product of all arguments. -- productOf :: forall a f. (Num a, FoldlApp a a f) => f productOf = foldlApp (*) (1 :: a) -- | Form a @NonEmpty@ list in reverse order from all arguments. -- reverseNonEmptyOf :: FoldlApp a (NonEmpty a) f => a -> f reverseNonEmptyOf = foldlApp (\(x:|xs) a -> a:|(x:xs)) . (:|[]) -- | Form a list in reverse order from all arguments. -- reverseOf :: forall a f. FoldlApp a [a] f => f reverseOf = foldlApp (flip (:)) ([] :: [a]) -- | Form a @Seq@ from all arguments. -- seqOf :: forall a f. FoldlApp a (Seq a) f => f seqOf = foldlApp (Seq.|>) (Seq.empty :: Seq a) -- | Form a @Seq@ in reverse order from all arguments. -- reverseSeqOf :: forall a f. FoldlApp a (Seq a) f => f reverseSeqOf = foldlApp (flip (Seq.<|)) (Seq.empty :: Seq a) -- | Form a @Set@ from all arguments. -- setOf :: forall a f. (Ord a, FoldlApp a (Set a) f) => f setOf = foldlApp (flip Set.insert) (Set.empty :: Set a) -- | Form a strict @IntMap@ from all arguments. -- strictIntMapOf :: forall a f. FoldlApp (StrictIntMap.Key, a) (IntMap a) f => f strictIntMapOf = foldlApp (flip (uncurry StrictIntMap.insert)) (StrictIntMap.empty :: IntMap a) -- -- | Form a strict @Map@ from all arguments. -- strictMapOf :: forall k a f. (Ord k, FoldlApp (k, a) (Map k a) f) => f strictMapOf = foldlApp (flip (uncurry StrictMap.insert)) (StrictMap.empty :: Map k a) -- -- | Return the sum of all arguments. -- sumOf :: forall a f. (Num a, FoldlApp a a f) => f sumOf = foldlApp (+) (0 :: a)