views:

472

answers:

5

I am reading this tutorial on Haskell. They define function composition as the following:

(.)                     :: (b->c) -> (a->b) -> (a->c)
f . g                   = \ x -> f (g x)

No examples were provided, which I believe would enlighten me as to what is being defined here.

Can someone provide a simple example (with explanation) of how function composition is used?

+8  A: 

The composition of f and g is a function that first applies g to its argument, then f to the value returned by g. It then returns the return value of f.

This identity may be enlightening:

f (g x) = (f . g) x

If you have a Java/C background, consider this example:

int f(int x);
int g(int x);
int theComposition(int x) { return f(g(x)); }
David Crawshaw
+1 for equivalence
outis
+2  A: 

From the HaskellWiki page on function composition:

desort = (reverse . sort)

Now desort is a function that sorts a list in reverse. Basically, desort feeds it's arguments into sort, and then feeds the return value from sort into reverse, an returns that. So it sorts it, and then it reverses the sorted list.

Chris Lutz
+2  A: 

This example is contrived, but suppose we have

sqr x = x * x  
inc x = x + 1

and we want to write a function that computes x^2+1. We can write

xSquaredPlusOne = inc . sqr

(which means

xSquaredPlusOne x = (inc . sqr) x

which means

xSquaredPlusOne x = inc(sqr x)

since f=inc and g=sqr).

Brian
+18  A: 

Function composition is a way to "compose" two functions together into a single function. Here's an example:

Say you have these functions:

even :: Int -> Bool
not :: Bool -> Bool

and you want to define your own myOdd :: Int -> Bool function using the two above.

The obvious way to do this is the following:

myOdd :: Int -> Bool
myOdd x = not (even x)

But this can be done more succinctly using function composition:

myOdd :: Int -> Bool
myOdd = not . even

The myOdd functions behave exactly the same, but the second one is created by "glue-ing" two functions together.

A scenario where this is especially useful is to remove the need for an explicit lambda. E.g:

map (\x -> not (even x)) [1..9]

can be rewritten to:

map (not . even) [1..9]

A bit shorter, less room for errors.

Tom Lokhorst
+3  A: 

Fun side note. Function composition is the equivalent of a syllogism in logic:

All men are mortal. Socrates is a man. Therefore, Socrates is mortal.

A syllogism composes two material implications into one:

(Man => Mortal), (Socrates => Man), therefore (Socrates => Mortal)

Therefore...

(B => C) => (A => B) => (A => C)

... which is the type of the . function.

Apocalisp