-- | This module is for convenience and demonstrative purposes -- more than it is for providing actual value. -- I do not recommend that you rely on this module -- for performance-sensitive code. -- Because this module is not based on Prelude's (.), -- some chances at optimization might be missed by your compiler. module Data.Composition ( -- * Math (∘) -- * Colons and dots , (.:) , (.:.) , (.::) , (.::.) , (.:::) , (.:::.) , (.::::) , (.::::.) -- * Asterisks , (.*) , (.**) , (.***) , (.****) , (.*****) , (.******) , (.*******) , (.********) -- * composeN , compose1 , compose2 , compose3 , compose4 , compose5 , compose6 , compose7 , compose8 , compose9 ) where -- Not exported. This is defined here to remove the dependency on base (.) :: (b -> c) -> (a -> b) -> a -> c (b -> c f . :: (b -> c) -> (a -> b) -> a -> c . a -> b g) a x = b -> c f (a -> b g a x) infixr 9 . -- | The mathematical symbol for function composition. (∘) :: (b -> c) -> (a -> b) -> a -> c ∘ :: (b -> c) -> (a -> b) -> a -> c (∘) = (b -> c) -> (a -> b) -> a -> c forall b c a. (b -> c) -> (a -> b) -> a -> c (.) infixr 9 ∘ -- | Compose two functions. @f .: g@ is similar to @f . g@ -- except that @g@ will be fed /two/ arguments instead of one -- before handing its result to @f@. -- -- This function is defined as -- -- > (f .: g) x y = f (g x y) -- -- Example usage: -- -- > concatMap :: (a -> [b]) -> [a] -> [b] -- > concatMap = concat .: map -- -- Notice how /two/ arguments -- (the function /and/ the list) -- will be given to @map@ before the result -- is passed to @concat@. This is equivalent to: -- -- > concatMap f xs = concat (map f xs) (.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d (c -> d f .: :: (c -> d) -> (a -> b -> c) -> a -> b -> d .: a -> b -> c g) a x b y = c -> d f (a -> b -> c g a x b y) infixr 8 .: -- | Equivalent to '.:' -- -- The pattern of appending asterisks is -- straightforward to extend to similar functions: -- (compose2 = .*, compose3 = .**, etc). -- However, @.:@ has been commonly adopted amongst Haskellers, -- and the need for compose3 and beyond is rare in practice. (.*) :: (c -> d) -> (a -> b -> c) -> a -> b -> d .* :: (c -> d) -> (a -> b -> c) -> a -> b -> d (.*) = ((b -> c) -> b -> d) -> (a -> b -> c) -> a -> b -> d forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((b -> c) -> b -> d) -> (a -> b -> c) -> a -> b -> d) -> ((c -> d) -> (b -> c) -> b -> d) -> (c -> d) -> (a -> b -> c) -> a -> b -> d forall b c a. (b -> c) -> (a -> b) -> a -> c . (c -> d) -> (b -> c) -> b -> d forall b c a. (b -> c) -> (a -> b) -> a -> c (.) infixr 8 .* (.**) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e .** :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e (.**) = ((b -> c -> d) -> b -> c -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((b -> c -> d) -> b -> c -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e) -> ((d -> e) -> (b -> c -> d) -> b -> c -> e) -> (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (b -> c -> d) -> b -> c -> e forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d (.*) .*** :: (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e (.***) = ((a -> b -> c -> d) -> a -> b -> c -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((a -> b -> c -> d) -> a -> b -> c -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e) -> ((d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e) -> (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e forall d e a b c. (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e (.**) .**** :: (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e (.****) = ((a -> a -> b -> c -> d) -> a -> a -> b -> c -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((a -> a -> b -> c -> d) -> a -> a -> b -> c -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e) -> ((d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e) -> (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e forall d e a a b c. (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e (.***) .***** :: (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e (.*****) = ((a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e) -> ((d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e) -> (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e forall d e a a a b c. (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e (.****) .****** :: (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e (.******) = ((a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e) -> ((d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e) -> (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e forall d e a a a a b c. (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e (.*****) .******* :: (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e (.*******) = ((a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e) -> ((d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e) -> (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e (.******) .******** :: (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e (.********) = ((a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c (.) (((a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e) -> ((d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e) -> (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e forall b c a. (b -> c) -> (a -> b) -> a -> c . (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e (.*******) infixr 8 .** infixr 8 .*** infixr 8 .**** infixr 8 .***** infixr 8 .****** infixr 8 .******* infixr 8 .******** -- | @composeN f g@ means give @g@ @N@ inputs -- and then pass its result to @f@. compose1 :: (b -> c) -> (a -> b) -> a -> c compose1 :: (b -> c) -> (a -> b) -> a -> c compose1 = (b -> c) -> (a -> b) -> a -> c forall b c a. (b -> c) -> (a -> b) -> a -> c (.) compose2 :: (c -> d) -> (a -> b -> c) -> a -> b -> d compose2 :: (c -> d) -> (a -> b -> c) -> a -> b -> d compose2 = (c -> d) -> (a -> b -> c) -> a -> b -> d forall c d a b. (c -> d) -> (a -> b -> c) -> a -> b -> d (.*) compose3 :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e compose3 :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e compose3 = (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e forall d e a b c. (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e (.**) compose4 :: (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e compose4 = (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e forall d e a a b c. (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e (.***) compose5 :: (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e compose5 = (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e forall d e a a a b c. (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e (.****) compose6 :: (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e compose6 = (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e forall d e a a a a b c. (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e (.*****) compose7 :: (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e compose7 = (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e (.******) compose8 :: (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e compose8 = (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e (.*******) compose9 :: (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e compose9 = (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e (.********) -- | One compact pattern for composition operators is to -- "count the dots after the first one", -- which begins with the common '.:', and proceeds by first -- appending another @.@ and then replacing it with @:@ (.:.) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e .:. :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e (.:.) = (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e forall d e a b c. (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e (.**) .:: :: (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e (.::) = (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e forall d e a a b c. (d -> e) -> (a -> a -> b -> c -> d) -> a -> a -> b -> c -> e (.***) .::. :: (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e (.::.) = (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e forall d e a a a b c. (d -> e) -> (a -> a -> a -> b -> c -> d) -> a -> a -> a -> b -> c -> e (.****) .::: :: (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e (.:::) = (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e forall d e a a a a b c. (d -> e) -> (a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> b -> c -> e (.*****) .:::. :: (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e (.:::.) = (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> b -> c -> e (.******) .:::: :: (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e (.::::) = (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> b -> c -> e (.*******) .::::. :: (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e (.::::.) = (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e forall d e a a a a a a a b c. (d -> e) -> (a -> a -> a -> a -> a -> a -> a -> b -> c -> d) -> a -> a -> a -> a -> a -> a -> a -> b -> c -> e (.********) infixr 8 .:. infixr 8 .:: infixr 8 .::. infixr 8 .::: infixr 8 .:::. infixr 8 .:::: infixr 8 .::::.