Portability | Haskell98 |
---|---|

Stability | provisional |

Maintainer | wren@community.haskell.org |

Pointless fun :)

# Multicomposition

Based on http://matt.immute.net/content/pointless-fun. These combinators allow you to easily modify the types of a many-argument function with syntax that looks like giving type signatures. For example,

foo :: A -> B -> C albert :: A -> X beth :: B -> Y carol :: C -> Z bar :: X -> Y -> Z bar = foo $:: albert ~> beth ~> carol

($::) :: (a -> b) -> ((a -> b) -> c -> d) -> c -> dSource

Lift a function for multicomposition. This is like the `::`

of a type signature.

(~>) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> dSource

Multicompose a function on the appropriate argument. This is
like the `->`

arrows in a type signature.

(!~>) :: (a -> b) -> (c -> d) -> (b -> c) -> a -> dSource

Multicompose a function on the appropriate argument, calling
the left function eagerly. That is, the resulting function will
be strict in `a`

if the left argument is strict in `a`

(assuming
the final function of the multicomposition, the one applied to
the return value, is also strict).

# Composition for arity 2

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

Binary composition: pass two args to the right argument before composing.

(f .: g) x y = f (g x y)

or,

f .: g = curry (f . uncurry g)

This is the same as the common idiom `(f .) . g`

but more easily
extended to multiple uses, due to the fixity declaration.

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

Secondary composition: compose the right argument on the second arg of the left argument.

(f .^ g) x y = f x (g y)

# Strict composition

(.!) :: (b -> c) -> (a -> b) -> a -> cSource

Function composition which calls the right-hand function eagerly; i.e., making the left-hand function strict in its first argument.

(f .! g) x = f $! g x

This defines the composition for the sub-category of strict
Haskell functions. If the `Functor`

class were parameterized by
the domain and codomain categories (e.g., a regular `Functor f`

would be `CFunctor (->) (->) f`

instead) then this would allow
us to define functors `CFunctor (->) (!->) f`

where
`fmap f . fmap g = fmap (f .! g)`

.