HORIZON HASKELLDocslts/ghc-10.0.x8fef28d2026-11-02Search packagesCtrl K
Theme: |

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8fef28d · 2026-11-02

Modulecomposition-prelude-3.0.1.0Haskell98

Control.Composition

Contents
  1. Postcomposition
  2. Precomposition
  3. Monadic postcomposition
  4. Monadic precomposition
  5. Between combinators
  6. Fancy function application
  7. Monadic helpers
  8. Monadic actions
  9. Composition with lists of functions
  10. Tuple helpers
  11. J inspired
  12. Reëxports from base
Synopsis

Postcomposition

value(.*) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
#
value(.**) :: (d -> e) -> (a -> b -> c -> d) -> a -> b -> c -> e
#
value(.***) :: (e -> f) -> (a -> b -> c -> d -> e) -> a -> b -> c -> d -> f
#
value(.****)
  1. :: f -> g
  2. -> a -> b -> c -> d -> e -> f
  3. -> a
  4. -> b
  5. -> c
  6. -> d
  7. -> e
  8. -> g
value(.*****)
  1. :: g -> h
  2. -> a -> b -> c -> d -> e -> f -> g
  3. -> a
  4. -> b
  5. -> c
  6. -> d
  7. -> e
  8. -> f
  9. -> h
value(.******)
  1. :: h -> i
  2. -> a -> b -> c -> d -> e -> f -> g -> h
  3. -> a
  4. -> b
  5. -> c
  6. -> d
  7. -> e
  8. -> f
  9. -> g
  10. -> i

Precomposition

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

Backwards function composition. This is a specialization of <&>, but it has a different fixity.

value(.@) :: (b -> c) -> (a -> c -> d) -> a -> b -> d
value(.@@) :: (c -> d) -> (a -> b -> d -> e) -> a -> b -> c -> e
value(.@@@) :: (d -> e) -> (a -> b -> c -> e -> f) -> a -> b -> c -> d -> f
value(.@@@@)
  1. :: e -> f
  2. -> a -> b -> c -> d -> f -> g
  3. -> a
  4. -> b
  5. -> c
  6. -> d
  7. -> e
  8. -> g
value(.@@@@@)
  1. :: f -> g
  2. -> a -> b -> c -> d -> e -> g -> h
  3. -> a
  4. -> b
  5. -> c
  6. -> d
  7. -> e
  8. -> f
  9. -> h

Monadic postcomposition

value(<=*<) :: Monad m => (c -> m d) -> (a -> b -> m c) -> a -> b -> m d

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
value(<=**<)
  1. :: Monad m
  2. => d -> m e
  3. -> a -> b -> c -> m d
  4. -> a
  5. -> b
  6. -> c
  7. -> m e

The bleeding fish operator

value(>=**>)
  1. :: Monad m
  2. => a -> b -> c -> m d
  3. -> d -> m e
  4. -> a
  5. -> b
  6. -> c
  7. -> m e
value(>=*>) :: Monad m => (a -> b -> m c) -> (c -> m d) -> a -> b -> m d

Compare >=>.

Monadic precomposition

value(<-=*<) :: Monad m => (b -> m c) -> (a -> c -> m d) -> a -> b -> m d
value(>-=*>) :: Monad m => (a -> c -> m d) -> (b -> m c) -> a -> b -> m d

Between combinators

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

Can be used to rewrite

\g -> f . g . h

to

between f h
value(~@~) :: (c -> d) -> (a -> b) -> (b -> c) -> a -> d
#
valuebetweenM :: Monad m => (c -> m d) -> (a -> m b) -> (b -> m c) -> a -> m d
#
value(<~@~<) :: Monad m => (c -> m d) -> (a -> m b) -> (b -> m c) -> a -> m d
#

Fancy function application

value(-$) :: (a -> b -> c) -> b -> a -> c

Backwards function application. This is an infix synonym for flip

Monadic helpers

value(.$) :: Monad m => m (m a) -> m a

Infix version of join

As an example, one could use this to rewrite

between (char '"') (char '"')

to

between .$ (char '"')

Or

fromEither :: Either a a -> a
fromEither = either id id

to

fromEither :: Either a a -> a
fromEither = either .$ id
valueonM :: Monad m => (b -> b -> m c) -> (a -> m b) -> a -> a -> m c
#

Monadic actions

Composition with lists of functions

Tuple helpers

valueboth :: (a -> b) -> (a, a) -> (b, b)
#
value(+>) :: (a -> b) -> (a, a) -> (b, b)

Infix synonym for both

J inspired

value(&:) :: (b -> b -> c) -> (a -> b) -> a -> a -> c

Pronounced 'appose'. Synonym for on

Reëxports from base

value(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c

Right-to-left composition of Kleisli arrows. (>=>), with the arguments flipped.

Note how this operator resembles function composition (.):

(.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
value(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c

Left-to-right composition of Kleisli arrows.

'(bs >=> cs) a' can be understood as the do expression

do b <- bs a
   cs b

or in terms of (>>=) as

bs a >>= cs
value(<**>) :: Applicative f => f a -> f (a -> b) -> f b

A variant of <*> with the types of the arguments reversed. It differs from flip (<*>) in that the effects are resolved in the order the arguments are presented.

Examples
Example1 expression
(<**>) (print 1) (id <$ print 2)12
Example1 expression
flip (<*>) (print 1) (id <$ print 2)21
Example1 expression
ZipList [4, 5, 6] <**> ZipList [(+1), (*2), (/3)]ZipList {getZipList = [5.0,10.0,2.0]}
value(&) :: a -> (a -> b) -> b

& is a reverse application operator. This provides notational convenience. Its precedence is one higher than that of the forward application operator $, which allows & to be nested in $.

This is a version of flip id, where id is specialized from a -> a to (a -> b) -> (a -> b) which by the associativity of (->) is (a -> b) -> a -> b. flipping this yields a -> (a -> b) -> b which is the type signature of &

Examples
Example1 expression
5 & (+1) & show"6"
Example1 expression
sqrt $ [1 / n^2 | n <- [1..1000]] & sum & (*6)3.1406380562059946
value(<&>) :: Functor f => f a -> (a -> b) -> f b

Flipped version of <$>.

(<&>) = flip fmap
Examples

Apply (+1) to a list, a Just and a Right:

Example1 expression
Just 2 <&> (+1)Just 3
Example1 expression
[1,2,3] <&> (+1)[2,3,4]
Example1 expression
Right 3 <&> (+1)Right 4
valuefix :: (a -> a) -> a

fix f is the least fixed point of the function f, i.e. the least defined x such that f x = x.

When f is strict, this means that because, by the definition of strictness, f ⊥ = ⊥ and such the least defined fixed point of any strict function is ⊥.

Examples

We can write the factorial function using direct recursion as

Example1 expression
let fac n = if n <= 1 then 1 else n * fac (n-1) in fac 5120

This uses the fact that Haskell’s let introduces recursive bindings. We can rewrite this definition using fix,

Instead of making a recursive call, we introduce a dummy parameter rec; when used within fix, this parameter then refers to fix’s argument, hence the recursion is reintroduced.

Example1 expression
fix (\rec n -> if n <= 1 then 1 else n * rec (n-1)) 5120

Using fix, we can implement versions of repeat as fix . (:) and cycle as fix . (++)

Example1 expression
take 10 $ fix (0:)[0,0,0,0,0,0,0,0,0,0]
Example1 expression
map (fix (\rec n -> if n < 2 then n else rec (n - 1) + rec (n - 2))) [1..10][1,1,2,3,5,8,13,21,34,55]
Implementation Details

The current implementation of fix uses structural sharing

fix f = let x = f x in x

A more straightforward but non-sharing version would look like

fix f = f (fix f)
valueon :: (b -> b -> c) -> (a -> b) -> a -> a -> c

on b u x y runs the binary function b on the results of applying unary function u to two arguments x and y. From the opposite perspective, it transforms two inputs and combines the outputs.

(op `on` f) x y = f x `op` f y
Examples
Example1 expression
sortBy (compare `on` length) [[0, 1, 2], [0, 1], [], [0]][[],[0],[0,1],[0,1,2]]
Example1 expression
((+) `on` length) [1, 2, 3] [-1]4
Example1 expression
((,) `on` (*2)) 2 3(4,6)
Algebraic properties
  • (*) `on` id = (*) -- (if (*) ∉ {⊥, const ⊥})
  • ((*) `on` f) `on` g = (*) `on` (f . g)
  • flip on f . flip on g = flip on (g . f)