Safe Haskell | Safe-Inferred |
---|

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!

- 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

module Data.Composition

(%.**) :: (c -> d) -> (a -> b -> c) -> a -> b -> dSource

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 -> eSource

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 -> fSource

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 -> dSource

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 -> eSource

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 -> fSource

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 -> dSource

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 -> eSource

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 -> fSource

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 -> eSource

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 -> fSource

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 -> gSource

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 -> eSource

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 -> fSource

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 -> gSource

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 -> eSource

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 -> fSource

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 -> gSource

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 -> gSource

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 -> gSource

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 aSource

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 -> cSource

Slightly Lower fixity function composition for use with

.
`?.`

(§) :: (a -> b) -> a -> bSource

Just like (

), but with higher precedence than (`$`

), but still lower
than (`<>`

). Similar to Diagrams.Util `.`

`'#'`

, but without flipped arguments.

(&&\) :: (a -> Bool) -> (a -> Bool) -> a -> BoolSource

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 -> BoolSource

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 bSource

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 bSource

fmap with its arguments reversed.

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

for = flip fmap with = flip fmap