Composition of Function Composition - (.).(.)
Tags: math, category, functional, haskell
Published: 2020-06-19 03:26:50

---
title: Composition of Function Composition - (.).(.)
published: true
description: 
tags: math, category, functional, haskell
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/10gv67usuo2uuuaurmtr.jpeg
---

You must be familiar with function composition.

{% katex %}
f : B \rightarrow C \newline
g : A \rightarrow B \newline
h = f \circ g \newline
h: A \rightarrow C
{% endkatex %}

Well, function composition itself is a function right? What do you think will happen when you compose compositions?

{% katex %}
(\circ) \circ (\circ) = ?
{% endkatex %}

It becomes another composition operator that can compose an unary function and a binary function. That is to say,

{% katex %}
f: C \rightarrow D \newline
g: A \times B \rightarrow C
{% endkatex %}

Now let {% katex inline %} h {% endkatex %} be
{% katex %}
h = f \left( (\circ) \circ (\circ) \right) g 
{% endkatex %}

Then {% katex inline %} h {% endkatex %} is

{% katex %}
h : A \times B \rightarrow D \newline
h(a,b) = f(g(a,b))
{% endkatex %}

We can go one step further and compose three compositions.

{% katex %}
f : D \rightarrow E \newline
g : A \times B \times C \rightarrow D \newline
h : A \times B \times C \rightarrow E \newline
h = f \left( (\circ) \circ (\circ) \circ (\circ) \right) g \newline
h(a,b,c) = f(g(a,b,c))
{% endkatex %}

It becomes a composition operator that can compose an unary function and a ternary function. In other words, the degree of the domain increases by 1 everytime we compose another composition.

You may be wondering how it is possible. You can try direct proof first to see the mechanism although it won’t tell you much about the idea behind it. I’ll put the brief, outline proof just to make the point of how unhelpful it is.

> Signature of function composition is
> 
> {% katex %}
> \circ: (\beta \rightarrow \gamma) \times (\alpha \rightarrow \beta) \rightarrow (\alpha \rightarrow \gamma)
> {% endkatex %}
>
> Both parameters are also composition functions therefore the signatures of {% katex inline %}\alpha, \beta, \gamma{% endkatex %} are
>
>{% katex %}
>\alpha : y \rightarrow z \newline
>\beta : (x \rightarrow y) \rightarrow (x \rightarrow z) \newline
>\gamma : (a \rightarrow (x \rightarrow y)) \rightarrow (a \rightarrow (x \rightarrow z))
>{% endkatex %}
>
> Therefore the signature of the outcome is
>
>{% katex %}
>\alpha \rightarrow \gamma = (y \rightarrow z) \rightarrow (a \rightarrow x \rightarrow y) \rightarrow (a \rightarrow x \rightarrow z)
>{% endkatex %}
> Which is the signature of unary-binary-composition function.

As you can see it doesn’t tell you **why**. It’s like saying {% katex inline %}2x{% endkatex %} is the slope of the tangent line of {% katex inline %}x^2{% endkatex %} without mentioning derivative.

If you know [Hom functor](https://en.wikipedia.org/wiki/Hom_functor) then much better explanation is possible.

You can consider a function composition as a hom-functor in category theory’s perspective. To present function composition as hom-functor:

{% katex %}
\circ_{hom(x,-)} : (y \rightarrow z) \rightarrow (y^x \rightarrow z^x)
{% endkatex %}

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/en7xeob875mxeqt9w06r.jpeg)

> ###### If you are not familiar with {% katex inline %}x^y{% endkatex %} notation, you can just think of it as a function {% katex inline %}y \rightarrow x{% endkatex %}

And here’s the composition of two function compositions

{% katex %}
\circ_{hom(x,-)} \circ \circ_{hom(a,-)} : (y \rightarrow z) \rightarrow (y^{xa} \rightarrow z^{xa})
{% endkatex %}

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/10gv67usuo2uuuaurmtr.jpeg)

You can construct {% katex inline %} h: x\times a \rightarrow z {%endkatex%} universally with {% katex inline %} f: y\rightarrow z {%endkatex%} and {% katex inline %} g: x\times a \rightarrow y {%endkatex%}

Here’s an application in programming. Say you are making a function that calculates a vector’s magnitude. It’s always encouraged to use squared magnitude instead of actual magnitude unless it’s absolutely necessary for performance reasons therefore you have to support both functionalities. You can implement `squaredMagnitude` first and then implement `magnitude` by composing `sqrt` and `squaredMagnitude` using the discussed method.

```haskell
(.*) :: (c -> d) -> (a -> b -> c) -> (a -> b -> d)
(.*) = (.) . (.)

squaredMagnitude :: Double -> Double -> Double
squaredMagnitude x y = x^2 + y^2

magnitude = sqrt .* squaredMagnitude

main :: IO ()
main = do
  print $ squaredMagnitude 3 4
  print $ magnitude 3 4
```

It outputs

```shell
25.0
5.0
```