composition-prelude 1.5.2.0 → 1.5.3.0
raw patch · 4 files changed
+239/−179 lines, 4 filesdep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Control.Composition: (<~@~<) :: Monad m => (c -> m d) -> (a -> m b) -> (b -> m c) -> a -> m d
+ Control.Composition: (~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Control.Composition: between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
+ Control.Composition: betweenM :: Monad m => (c -> m d) -> (a -> m b) -> (b -> m c) -> a -> m d
- Control.Composition: threadM :: (Monad m, Foldable t) => t (a -> m a) -> a -> m a
+ Control.Composition: threadM :: (Monad m, Foldable t, Applicative m) => t (a -> m a) -> a -> m a
Files
- CHANGELOG.md +4/−0
- composition-prelude.cabal +3/−3
- src/Control/Composition.cpphs +232/−0
- src/Control/Composition.hs +0/−176
CHANGELOG.md view
@@ -1,5 +1,9 @@ # composition-prelude +# 1.5.3.0++ * Add `between` and `~@~`+ # 1.5.2.0 * Add monadic versions of various composition operators.
composition-prelude.cabal view
@@ -1,12 +1,11 @@ cabal-version: 1.18 name: composition-prelude-version: 1.5.2.0+version: 1.5.3.0 license: BSD3 license-file: LICENSE copyright: Copyright: (c) 2017-2018 Vanessa McHale maintainer: vamchale@gmail.com author: Vanessa McHale-tested-with: ghc ==8.4.3 ghc ==8.6.1 bug-reports: https://hub.darcs.net/vmchale/composition-prelude/issues synopsis: Higher-order function combinators description:@@ -29,11 +28,12 @@ library exposed-modules: Control.Composition+ build-tools: cpphs -any hs-source-dirs: src default-language: Haskell98 ghc-options: -Wall build-depends:- base >=4.11 && <5+ base >=4.3 && <5 if flag(development) ghc-options: -Werror
+ src/Control/Composition.cpphs view
@@ -0,0 +1,232 @@+module Control.Composition+ ( -- * Postcomposition+ (.*)+ , (.**)+ , (.***)+ , (.****)+ -- * Precomposition+ , (-.)+ , (-.*)+ , (-.**)+ , (-.***)+ , (-.****)+ -- * Monadic composition+ , (<=<)+ , (>=>)+ -- * Monadic postcomposition+ , (<=*<)+ , (<=**<)+ , (>=**>)+ , (>=*>)+ -- * Monadic precomposition+ , (<-=*<)+ , (>-=*>)+ , (<-=**<)+ , (>-=**>)+ -- * Between combinators+ , between+ , (~@~)+ , betweenM+ , (<~@~<)+ -- * Fancy function application+ , (-$)+ -- * Monadic helpers+ , bisequence'+ -- * Monadic actions+ , axe+ , biaxe+ -- * Composition with lists of functions+ , thread+ , threadM+ -- * Tuple helpers+ , both+ -- * Reëxports from base+ , (&)+ , (<&>)+ , fix+ , on+ ) where++import Control.Applicative+import Control.Arrow ((***))+import Control.Monad+import Data.Foldable+import Data.Traversable+#if MIN_VERSION_base(4,8,0)+import Data.Function (fix, on, (&))+#else+import Data.Function (fix, on)+#endif+#if MIN_VERSION_base(4,11,0)+import Data.Functor ((<&>))+#endif+import Prelude hiding (foldr)++infixr 8 .*+infixr 8 .**+infixr 8 .***+infixr 8 .****+infixr 8 -.*+infixr 8 -.**+infixr 8 -.***+infixr 8 -.****+infixl 8 -$+infixl 8 ~@~+infixl 8 <~@~<+#if !MIN_VERSION_base(4,11,0)+infixl 1 <&>+#endif+#if !MIN_VERSION_base(4,8,0)+infixl 1 &+#endif++axe :: (Traversable t, Applicative f) => t (a -> f ()) -> a -> f ()+axe = sequenceA_ .* sequenceA++bisequence' :: (Traversable t, Applicative f) => t (a -> b -> f c) -> a -> b -> t (f c)+bisequence' = sequenceA .* sequenceA++biaxe :: (Traversable t, Applicative f) => t (a -> b -> f ()) -> a -> b -> f ()+biaxe = sequenceA_ .** bisequence'++both :: (a -> b) -> (a, a) -> (b, b)+both = join (***)++-- | Backwards function application+(-$) :: (a -> b -> c) -> b -> a -> c+(-$) = flip++-- | As an example:+--+-- > λ:> ((*2) .* (+)) 1 3 4+-- > 16+(.*) :: (c -> d) -> (a -> b -> c) -> a -> b -> d+(.*) f g = \x y -> f (g x y) -- FIXME use lambda approach for better inlining? Like (.) does++(.**) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e+(.**) f g = \x y z -> f (g x y z)++(.***) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f+(.***) f g = \w x y z -> f (g w x y z)++(.****) :: (f -> g) -> (a -> b -> c -> d -> e -> f) -> a -> b -> c -> d -> e -> g+(.****) f g = \v w x y z -> f (g v w x y z)++-- | A monadic version of '.*'. Compare '<=<'.+--+-- As an example, one could use this to rewrite+--+-- > \x y z -> f (g x y z) z+--+-- to+--+-- > f <=*< g+--+-- @since 1.5.2.0+(<=*<) :: Monad m => (c -> m d) -> (a -> b -> m c) -> a -> b -> m d+(<=*<) f g = \x y -> f =<< g x y++-- | The bleeding fish operator+--+-- @since 1.5.2.0+(<=**<) :: Monad m => (d -> m e) -> (a -> b -> c -> m d) -> a -> b -> c -> m e+(<=**<) f g = \x y z -> f =<< g x y z++-- | Compare '>=>'.+--+-- @since 1.5.2.0+(>=*>) :: Monad m => (a -> b -> m c) -> (c -> m d) -> a -> b -> m d+(>=*>) g f = \x y -> f =<< g x y++-- | @since 1.5.2.0+(>=**>) :: Monad m => (a -> b -> c -> m d) -> (d -> m e) -> a -> b -> c -> m e+(>=**>) g f = \x y z -> f =<< g x y z++-- | @since 1.5.2.0+(<-=*<) :: Monad m => (b -> m c) -> (a -> c -> m d) -> a -> b -> m d+(<-=*<) f g = \x y -> g x =<< f y++-- | @since 1.5.2.0+(>-=*>) :: Monad m => (a -> c -> m d) -> (b -> m c) -> a -> b -> m d+(>-=*>) g f = \x y -> g x =<< f y++-- | @since 1.5.2.0+(<-=**<) :: Monad m => (c -> m d) -> (a -> b -> d -> m e) -> a -> b -> c -> m e+(<-=**<) f g = \x y z -> g x y =<< f z++-- | @since 1.5.2.0+(>-=**>) :: Monad m => (a -> b -> d -> m e) -> (c -> m d) -> a -> b -> c -> m e+(>-=**>) g f = \x y z -> g x y =<< f z++-- | The Oedipus combinator+(-.*) :: (b -> c) -> (a -> c -> d) -> a -> b -> d+(-.*) f g = \x y -> g x (f y)++(-.**) :: (c -> d) -> (a -> b -> d -> e) -> a -> b -> c -> e+(-.**) f g = \x y z -> g x y (f z)++(-.***) :: (d -> e) -> (a -> b -> c -> e -> f) -> a -> b -> c -> d -> f+(-.***) f g = \w x y z -> g w x y (f z)++(-.****) :: (e -> f) -> (a -> b -> c -> d -> f -> g) -> a -> b -> c -> d -> e -> g+(-.****) f g = \v w x y z -> g v w x y (f z)++-- | Backwards function composition. This is a specialization of '<&>'.+(-.) :: (a -> b) -> (b -> c) -> a -> c+(-.) = (<&>)++{-# RULES+ "thread" forall f g. thread [f, g] = f . g;+ "thread" forall f g h. thread [f, g, h] = f . g . h;+ "thread" forall f fs. thread (f:fs) = f . thread fs+ #-}++thread :: Foldable t => t (a -> a) -> a -> a+thread = foldr (.) id++{-# INLINE [1] thread #-}++threadM :: (Monad m, Foldable t, Applicative m) => t (a -> m a) -> a -> m a+threadM = foldr (<=<) pure++{-# INLINE [1] threadM #-}++{-# RULES+ "threadM" forall f g. threadM [f, g] = f <=< g;+ "threadM" forall f g h. threadM [f, g, h] = f <=< g <=< h;+ "threadM" forall f fs. threadM (f:fs) = f <=< threadM fs+ #-}++-- | Can be used to rewrite+--+-- > \g -> f . g . h+--+-- to+--+-- > between f h+--+-- @since 1.5.3.0+between :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+between f g = (f .) . (. g)++-- @since 1.5.3.0+betweenM :: Monad m => (c -> m d) -> (a -> m b) -> (b -> m c) -> a -> m d+betweenM f g = \h -> f <=< h <=< g++-- @since 1.5.3.0+(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d+(~@~) = between++-- @since 1.5.3.0+(<~@~<) :: Monad m => (c -> m d) -> (a -> m b) -> (b -> m c) -> a -> m d+(<~@~<) = betweenM++#if !MIN_VERSION_base(4,11,0)+(<&>) :: Functor f => f a -> (a -> b) -> f b+(<&>) = flip fmap+#endif++#if !MIN_VERSION_base(4,8,0)+(&) :: a -> (a -> b) -> b+x & f = f x+#endif
− src/Control/Composition.hs
@@ -1,176 +0,0 @@-module Control.Composition- ( -- * Postcomposition- (.*)- , (.**)- , (.***)- , (.****)- -- * Precomposition- , (-.)- , (-.*)- , (-.**)- , (-.***)- , (-.****)- -- * Monadic composition- , (<=<)- , (>=>)- -- * Monadic postcomposition- , (<=*<)- , (<=**<)- , (>=**>)- , (>=*>)- -- * Monadic precomposition- , (<-=*<)- , (>-=*>)- , (<-=**<)- , (>-=**>)- -- * Fancy function application- , (-$)- -- * Monadic helpers- , bisequence'- -- * Monadic actions- , axe- , biaxe- -- * Composition with lists of functions- , thread- , threadM- -- * Tuple helpers- , both- -- * Reëxports from base- , (&)- , (<&>)- , fix- , on- ) where--import Control.Arrow ((***))-import Control.Monad-import Data.Foldable (sequenceA_)-import Data.Function (fix, on, (&))-import Data.Functor ((<&>))--infixr 8 .*-infixr 8 .**-infixr 8 .***-infixr 8 .****-infixr 8 -.*-infixr 8 -.**-infixr 8 -.***-infixr 8 -.****-infixl 8 -$--axe :: (Traversable t, Applicative f) => t (a -> f ()) -> a -> f ()-axe = sequenceA_ .* sequenceA--bisequence' :: (Traversable t, Applicative f) => t (a -> b -> f c) -> a -> b -> t (f c)-bisequence' = sequenceA .* sequenceA--biaxe :: (Traversable t, Applicative f) => t (a -> b -> f ()) -> a -> b -> f ()-biaxe = sequenceA_ .** bisequence'--both :: (a -> b) -> (a, a) -> (b, b)-both = join (***)---- | Backwards function application-(-$) :: (a -> b -> c) -> b -> a -> c-(-$) = flip---- | As an example:------ > λ:> ((*2) .* (+)) 1 3 4--- > 16-(.*) :: (c -> d) -> (a -> b -> c) -> a -> b -> d-(.*) f g = \x y -> f (g x y) -- FIXME use lambda approach for better inlining? Like (.) does--(.**) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e-(.**) f g = \x y z -> f (g x y z)--(.***) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f-(.***) f g = \w x y z -> f (g w x y z)--(.****) :: (f -> g) -> (a -> b -> c -> d -> e -> f) -> a -> b -> c -> d -> e -> g-(.****) f g = \v w x y z -> f (g v w x y z)---- | A monadic version of '.*'. Compare '<=<'.------ As an example, one could use this to rewrite------ > \x y z -> f (g x y z) z------ to------ > f <=*< g------ @since 1.5.2.0-(<=*<) :: Monad m => (c -> m d) -> (a -> b -> m c) -> a -> b -> m d-(<=*<) f g = \x y -> f =<< g x y---- | The bleeding fish operator------ @since 1.5.2.0-(<=**<) :: Monad m => (d -> m e) -> (a -> b -> c -> m d) -> a -> b -> c -> m e-(<=**<) f g = \x y z -> f =<< g x y z---- | Compare '>=>'.------ @since 1.5.2.0-(>=*>) :: Monad m => (a -> b -> m c) -> (c -> m d) -> a -> b -> m d-(>=*>) g f = \x y -> f =<< g x y---- | @since 1.5.2.0-(>=**>) :: Monad m => (a -> b -> c -> m d) -> (d -> m e) -> a -> b -> c -> m e-(>=**>) g f = \x y z -> f =<< g x y z---- | @since 1.5.2.0-(<-=*<) :: Monad m => (b -> m c) -> (a -> c -> m d) -> a -> b -> m d-(<-=*<) f g = \x y -> g x =<< f y---- | @since 1.5.2.0-(>-=*>) :: Monad m => (a -> c -> m d) -> (b -> m c) -> a -> b -> m d-(>-=*>) g f = \x y -> g x =<< f y---- | @since 1.5.2.0-(<-=**<) :: Monad m => (c -> m d) -> (a -> b -> d -> m e) -> a -> b -> c -> m e-(<-=**<) f g = \x y z -> g x y =<< f z---- | @since 1.5.2.0-(>-=**>) :: Monad m => (a -> b -> d -> m e) -> (c -> m d) -> a -> b -> c -> m e-(>-=**>) g f = \x y z -> g x y =<< f z---- | The Oedipus combinator-(-.*) :: (b -> c) -> (a -> c -> d) -> a -> b -> d-(-.*) f g = \x y -> g x (f y)--(-.**) :: (c -> d) -> (a -> b -> d -> e) -> a -> b -> c -> e-(-.**) f g = \x y z -> g x y (f z)--(-.***) :: (d -> e) -> (a -> b -> c -> e -> f) -> a -> b -> c -> d -> f-(-.***) f g = \w x y z -> g w x y (f z)--(-.****) :: (e -> f) -> (a -> b -> c -> d -> f -> g) -> a -> b -> c -> d -> e -> g-(-.****) f g = \v w x y z -> g v w x y (f z)---- | Backwards function composition. This is a specialization of '<&>'.-(-.) :: (a -> b) -> (b -> c) -> a -> c-(-.) = (<&>)--{-# RULES- "thread" forall f g. thread [f, g] = f . g;- "thread" forall f g h. thread [f, g, h] = f . g . h;- "thread" forall f fs. thread (f:fs) = f . thread fs- #-}--thread :: Foldable t => t (a -> a) -> a -> a-thread = foldr (.) id--{-# INLINE [1] thread #-}--threadM :: (Monad m, Foldable t) => t (a -> m a) -> a -> m a-threadM = foldr (<=<) pure--{-# INLINE [1] threadM #-}--{-# RULES- "threadM" forall f g. threadM [f, g] = f <=< g;- "threadM" forall f g h. threadM [f, g, h] = f <=< g <=< h;- "threadM" forall f fs. threadM (f:fs) = f <=< threadM fs- #-}