The Application and Composition Operators ========================================= .. note:: :doc:`This is a literate Haskell page: you can load it directly into ghci by following these steps `. The Composition Operator ------------------------ Composing functions is a common and useful way to create new functions in Haskell_. In mathematics, if you have two functions :math:`f(x)` and :math:`g(x)`, you compute their composition as :math:`f(g(x))`. Often we don't write the :math:`x`, and so can re-state this as follows: the composition of :math:`f` and :math:`g` is :math:`f \circ g`. Haskell_ mimics this notation by using ``.`` to compose functions. For example:: > f :: Int -> Int > f n = n + 1 > > g :: Int -> Int > g n = 2*n - 1 > > fg = f . g -- fg is the composition of f and g For example:: > f(g(3)) 6 > fg(3) 6 What is the type of ``.``? Try to think about this a little bit first before looking at the answer! According to Haskell_:: > :type (.) -- . must be written (.) to avoid a parser error (.) :: (b -> c) -> (a -> b) -> a -> c That's quite a mouthful! To understand it, consider this function definition:: h = f . g The signature for ``.`` says that ``f`` has the type ``b -> c``, ``g`` has the type ``a -> b``, and ``h`` has the type ``a -> c``. The type for ``h`` is not in brackets so that it can be curried. It is easiest to understand the type of ``f . g`` by examining the expression ``f (g x)``. If ``g`` takes an input of type ``a`` and returns an output of type ``b``, then that means the input type to ``f`` must be ``b``. The output of ``f`` can be any type ``c``. The input type of ``h`` must match the input type of ``g``, i.e. it must be ``a``. Similarly, ``h`` must match the output type of ``f``, so its output is ``c``. Take some time to work through this and understand why all the types are what they are. A good trick to remember is to start by giving ``g`` (the second input to ``.``) the type ``a -> b``. One of the uses of ``.`` in Haskell_ is to cut down on brackets. For example, here are two equivalent ways to do the same calculation:: > sqrt (abs (negate 2)) -- writing -2 gives a parser error, so we use 1.4142135623730951 -- negate instead > (sqrt . abs . negate) 2 1.4142135623730951 ``.`` also lets us define functions more compactly. Compare these two equivalent function definitions:: > root1 :: Float -> Float > root1 x = sqrt (abs (negate x)) > > root2 :: Float -> Float > root2 = sqrt . abs . negate ``root2`` is written in what is sometimes called a **point free** style. All it means is that the input parameter, ``x`` in this case, is not written explicitly. The difference between function *composition* and regular function *application* can sometimes seem confusing. So it is helpful to remember this example:: -- Composition f (g (h x)) -- these two expressions evaluate (f . g . h) x -- to the same thing -- Application f g h x -- these two expressions evaluate ((f g) h) x -- to the same thing -- (but probably not the same as the two -- previous composition expressions!) A function application like ``f g h x`` is a call to the function ``f``, and ``g``, ``h``, and ``x`` are the parameters passed to it. The parameters are passed in the order they are given, i.e. first ``g`` is passed to ``f``, then ``h``, and finally ``x``. Thus, function application is left-associative. $: The Application Operator --------------------------- The ``$`` operator may seem unusual first since its definition is so simple:: ($) :: (a -> b) -> a -> b f $ x = f x ``$`` is called the **function application** operator, and if you read its implementation you can see that, apparently, ``f $ x`` is the same as ``f x``. So what is the point of ``$``? What makes ``$`` useful is that it has the lowest possible precedence for any infix operator. Recall that for infix operators it is necessary to assign a precedence so we know in what order to evaluate them. For example, in math, when we evaluate the expression :math:`2 + 3\cdot 4`, we know to evaluate the :math:`\cdot` first because multiplication has a higher precedence than addition. The ``:info`` command will show you the precedence of an infix operator, e.g.:: > :info ($) -- $ must be written ($) to avoid a parser error ($) :: (a -> b) -> a -> b -- Defined in `GHC.Base' infixr 0 $ So if you see a ``$`` in a Haskell_ expression, it is evaluated *last* because it has such low priority. It essentially changes function application *right-associative* instead of the (default) left-associative. The main use of ``$`` is to simplify some expressions by removing brackets. For example:: > sum (map (+1) [1,2,3]) 9 Brackets are necessary around the ``map`` expression. If you left them out, ``sum`` would try to apply itself to ``map``, which results in an error:: > sum map (+1) [1,2,3] Couldn't match expected type `[(a1 -> a1) -> [t1] -> t0]' with actual type `(a0 -> b0) -> [a0] -> [b0]' In the first argument of `sum', namely `map' In the expression: sum map (+ 1) [1, 2, 3] In an equation for `it': it = sum map (+ 1) [1, 2, 3] But by using ``$``, we can make the function application right-associative, and thus get rid of a pair of brackets:: > sum $ map (+1) [1,2,3] 9 Remember, the trick with ``$`` is that it has the lowest possible precedence of all infix operators, and so when you see it in an expression that means it is evaluated *last*. So in this example ``map (+1) [1,2,3]`` is evaluated first, and then ``sum`` is applied to its result --- which is exactly how we want to do things.