altcomposition-0.2.3.0: Alternative combinators for unorthodox function composition

Safe Haskell Safe Haskell2010

Data.AltComposition

Description

Compose functions with higher arity.

Ever tried something like this:

(length . (++)) stringA stringB

Only to find out that you can't? The second function takes two parameters, and as such the simple function composition does not work.

A well known solution to this problem is this fun operator:

(.).(.) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)

And this is quite general:

((.).(.).(.)) :: (d -> e) -> (a -> b -> c -> d) -> (a -> b -> c -> e)

See the following link to gain a intuition for how this works: https://stackoverflow.com/questions/17585649/composing-function-composition-how-does-work

However, in real use these suffer from some problems, namely:

• They cannot be used infix, even with ticks (at least in ghci).
• They are quite verbose.

Then, someone thought about using a new symbol instead:

(.:) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)

And for each new parameter, you would add a dot

(.:.) :: (d -> e) -> (a -> b -> c -> d) -> (a -> b -> c -> e)

And so on, to .::, .::., etc. This is the approach taken by the "composition" package, which inspired this one. It can be found at:

http://hackage.haskell.org/package/composition

This package is included in (and re-exported from) this AltComposition.

So, why define a new package?

It does not scale well for other combinations. Let say I want (+) . (*), a function that takes three parameters, uses the first two in the multiplication, and then adds the third parameter with the result. And what if I want to feed to the first binary function as the second parameter of the second function?

The scheme proposed here is a little more verbose than the one from the "composition" package, but it allows for a precise indication of where the result of the first function is applied on the second function using the % symbol (remember printf %). So, the following operator:

*%*.**

Takes a binary function, and composes it with a ternary function, aplying its result as the middle parameter.

Its all a matter of opinion, and I strongly recomend that you use standard haskell syntax instead of these, for more portable code.

Also, many of these verbose operators have simpler counterparts. This is either noted as Deprecation, or a single note.

However, I still find myself writing the *%.*** operators myself, and I trust the deprecations to warn me about the simpler alternatives.

If you need even higher arity, first check your code, then refactor your code, and if you still need it, please send a pull request!

Synopsis

• module Data.Composition
• (%.**) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
• (%.***) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
• (%.****) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f
• (%*.*) :: (b -> c -> d) -> (a -> b) -> a -> c -> d
• (%*.**) :: (c -> d -> e) -> (a -> b -> c) -> a -> b -> d -> e
• (%*.***) :: (d -> e -> f) -> (a -> b -> c -> d) -> a -> b -> c -> e -> f
• (*%.*) :: (b -> c -> d) -> (a -> c) -> a -> b -> d
• (*%.**) :: (c -> d -> e) -> (a -> b -> d) -> a -> b -> c -> e
• (*%.***) :: (d -> e -> f) -> (a -> b -> c -> e) -> a -> b -> c -> d -> f
• (%**.*) :: (b -> c -> d -> e) -> (a -> b) -> a -> c -> d -> e
• (%**.**) :: (c -> d -> e -> f) -> (a -> b -> c) -> a -> b -> d -> e -> f
• (%**.***) :: (f -> d -> e -> g) -> (a -> b -> c -> f) -> a -> b -> c -> d -> e -> g
• (*%*.*) :: (b -> c -> d -> e) -> (a -> c) -> a -> b -> d -> e
• (*%*.**) :: (c -> d -> e -> f) -> (a -> b -> d) -> a -> b -> c -> e -> f
• (*%*.***) :: (d -> f -> e -> g) -> (a -> b -> c -> f) -> a -> b -> c -> d -> e -> g
• (**%.*) :: (b -> c -> d -> e) -> (a -> d) -> a -> b -> c -> e
• (**%.**) :: (c -> d -> e -> f) -> (a -> b -> e) -> a -> b -> c -> d -> f
• (**%.***) :: (d -> e -> f -> g) -> (a -> b -> c -> f) -> a -> b -> c -> d -> e -> g
• (%***.*) :: (f -> b -> c -> d -> g) -> (a -> f) -> a -> b -> c -> d -> g
• (%***.**) :: (f -> c -> d -> e -> g) -> (a -> b -> f) -> a -> b -> c -> d -> e -> g
• (?.) :: Category cat => Bool -> cat a a -> cat a a
• (.$) :: (b -> c) -> (a -> b) -> a -> c • § :: (a -> b) -> a -> b • (&&\) :: (a -> Bool) -> (a -> Bool) -> a -> Bool • (||\) :: (a -> Bool) -> (a -> Bool) -> a -> Bool • for :: Functor f => f a -> (a -> b) -> f b • with :: Functor f => f a -> (a -> b) -> f b # Documentation (%.**) :: (c -> d) -> (a -> b -> c) -> a -> b -> d infixr 9 Source # Compose a binary function with a unitary function Note: you should use idiomatic haskell instead (.).(.) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d) (f %.** g) x y = f (g x y) (f .: g) x y = f (g x y) (%.***) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e infixr 9 Source # Compose a ternary function with a unitary function Note: you should use idiomatic haskell instead (.).(.).(.) :: (d -> e) -> (a -> b -> c -> d) -> (a -> b -> c -> e) (f %.*** g) x y z = f (g x y z) (f .:. g) x y z = f (g x y z) (%.****) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f infixr 9 Source # Compose a quaternary function with a unitary function Note: you should use idiomatic haskell instead (.).(.).(.).(.) :: (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) w x y z = f (g w x y z) (%*.*) :: (b -> c -> d) -> (a -> b) -> a -> c -> d infixr 9 Source # Deprecated: This is the same as just (.) Compose a unary function with a binary function, applying the result of the unary function as the first parameter of the binary function. Note: DO NOT USE. Equivalent to .. (f %*.* g) x y = f (g x) y <=> f . g (%*.**) :: (c -> d -> e) -> (a -> b -> c) -> a -> b -> d -> e infixr 9 Source # Deprecated: Use f %.** g or .: instead Compose a binary function with another binary function, applying the result of the first binary function as the first parameter of the second binary function. Note: DO NOT USE. Equivalent to flip f . g. (f %*.** g) x y z = f (g x y) z (%*.***) :: (d -> e -> f) -> (a -> b -> c -> d) -> a -> b -> c -> e -> f infix 9 Source # Deprecated: Use f %.*** g or f .:. instead Compose a ternary function with a binary function, applying the result of the ternary function as the first parameter of the binary function. (f %*.*** g) x y w z = f (g x y w) z (*%.*) :: (b -> c -> d) -> (a -> c) -> a -> b -> d infixr 9 Source # Compose a unary function with a binary function, applying the result of the unary function as the second parameter of the binary function. Note: DO NOT USE. Equivalent to flip f . g. (f *%.* g) x y = f y (g x) (*%.**) :: (c -> d -> e) -> (a -> b -> d) -> a -> b -> c -> e infixr 9 Source # Compose a binary function with another binary function, applying the result of the first binary function as the second parameter of the second binary function. Note: DO NOT USE. Equivalent to flip f .: g or flip f %.** g. (f *%.** g) x y z = f z (g x y) (*%.***) :: (d -> e -> f) -> (a -> b -> c -> e) -> a -> b -> c -> d -> f infix 9 Source # Compose a ternary function with a binary function, applying the result of the ternary function as the second parameter of the binary function. Note: DO NOT USE. Equivalent to flip f .:. g or flip f %.*** g. (f *%.*** g) x y w z = f z (g x y w) (%**.*) :: (b -> c -> d -> e) -> (a -> b) -> a -> c -> d -> e infix 9 Source # Deprecated: This is the same as just (.) Compose a unary function with a ternary function, applying the result of the unary function as the first parameter of the ternary function. Note: DO NOT USE. Equivalent to .. (f %**.* g) x y z = f (g x) y z (%**.**) :: (c -> d -> e -> f) -> (a -> b -> c) -> a -> b -> d -> e -> f infix 9 Source # Deprecated: Use f %.** g or f .: instead Compose a binary function with a ternary function, applying the result of the binary function as the first parameter of the ternary function. (f %**.** g) x y w z = f (g x y) w z (%**.***) :: (f -> d -> e -> g) -> (a -> b -> c -> f) -> a -> b -> c -> d -> e -> g infix 9 Source # Deprecated: Use f %.*** g or f .:. instead Compose a ternary function with another ternary function, applying the result of the first ternary function as the first parameter of the last ternary function. (f %**.*** g) v w x y z = f (g v w x) y z (*%*.*) :: (b -> c -> d -> e) -> (a -> c) -> a -> b -> d -> e infix 9 Source # Compose a unary function with a ternary function, applying the result of the unary function as the second parameter of the ternary function. (f *%*.* g) x y z = f y (g x) z (*%*.**) :: (c -> d -> e -> f) -> (a -> b -> d) -> a -> b -> c -> e -> f infix 9 Source # Deprecated: Use f *%.** g instead Compose a binary function with a ternary function, applying the result of the binary function as the second parameter of the ternary function. Note: DO NOT USE. Equivalent to flip f .: g or flip f %.** g. (f *%*.** g) x y w z = f w (g x y) z (*%*.***) :: (d -> f -> e -> g) -> (a -> b -> c -> f) -> a -> b -> c -> d -> e -> g infix 9 Source # Deprecated: Use f *%.*** g instead Compose a ternary function with another ternary function, applying the result of the first ternary function as the second parameter of the last ternary function. Note: DO NOT USE. Equivalent to flip f .:. g or flip f %.*** g. (f *%*.*** g) v w x y z = f y (g v w x) z (**%.*) :: (b -> c -> d -> e) -> (a -> d) -> a -> b -> c -> e infix 9 Source # Compose a unary function with a ternary function, applying the result of the unary function as the third parameter of the ternary function. (f **%.* g) x y z = f y z (g x) (**%.**) :: (c -> d -> e -> f) -> (a -> b -> e) -> a -> b -> c -> d -> f infix 9 Source # Compose a binary function with a ternary function, applying the result of the binary function as the third parameter of the ternary function. (f **%.** g) x y w z = f w z (g x y) (**%.***) :: (d -> e -> f -> g) -> (a -> b -> c -> f) -> a -> b -> c -> d -> e -> g infix 9 Source # Compose a ternary function with another ternary function, applying the result of the first ternary function as the third parameter of the last ternary function. (f **%.*** g) v w x y z = f y z (g v w x) (%***.*) :: (f -> b -> c -> d -> g) -> (a -> f) -> a -> b -> c -> d -> g infix 9 Source # Deprecated: This is the same as just (.) Compose a unary function with a quaternary function, applying the result of the first unary function as the first parameter of the quaternary function. (f %***.* g) w x y z = f (g w) x y z (%***.**) :: (f -> c -> d -> e -> g) -> (a -> b -> f) -> a -> b -> c -> d -> e -> g infix 9 Source # Deprecated: This is the same as just %.** or .: Compose a binary function with a quaternary function, applying the result of the first binary function as the first parameter of the quaternary function. (f %***.** g) v w x y z = f (g v w) x y z (?.) :: Category cat => Bool -> cat a a -> cat a a Source # Conditional composition. Borrowed (and modified) from http://hackage.haskell.org/package/cond-0.4.0.2 If the predicate is False, id is returned instead of the second argument. This function, for example, can be used to conditionally add functions to a composition chain. (.$) :: (b -> c) -> (a -> b) -> a -> c infixl 8 Source #

Slightly Lower fixity function composition for use with ?..

§ :: (a -> b) -> a -> b infixr 8 Source #

Just like (\$), but with higher precedence than (<>), but still lower than (.). Similar to Diagrams.Util #, but without flipped arguments.

(&&\) :: (a -> Bool) -> (a -> Bool) -> a -> Bool infixr 3 Source #

Group conditions with &&. Useful for filter.

Note: an easy mnemonic to remember is that operators ending in \ (lambda) imply that their parameters are functions instead of values (in this particular case, boolean tests)

(f &&\ g) x = f x && g x

(||\) :: (a -> Bool) -> (a -> Bool) -> a -> Bool infixr 2 Source #

Group conditions with || Useful for filter.

Note: an easy mnemonic to remember is that operators ending in \ (lambda) imply that their parameters are functions instead of values (in this particular case, boolean tests)

(f ||\ g) x = f x || g x

for :: Functor f => f a -> (a -> b) -> f b Source #

fmap with its arguments reversed.

http://www.reddit.com/r/haskell/comments/qy990/suggestion_for_flip_map/

for  = flip fmap
with = flip fmap

with :: Functor f => f a -> (a -> b) -> f b Source #

fmap with its arguments reversed.

http://www.reddit.com/r/haskell/comments/qy990/suggestion_for_flip_map/

for  = flip fmap
with = flip fmap