## DEV Community is a community of 862,249 amazing developers

We're a place where coders share, stay up-to-date and grow their careers. Ingun 전인건

Posted on • Updated on

# Composition of Function Composition - (.).(.)

You must be familiar with function composition.

$f : B \rightarrow C \newline g : A \rightarrow B \newline h = f \circ g \newline h: A \rightarrow C$

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

$(\circ) \circ (\circ) = ?$

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

$f: C \rightarrow D \newline g: A \times B \rightarrow C$

Now let $h$ be

$h = f \left( (\circ) \circ (\circ) \right) g$

Then $h$ is

$h : A \times B \rightarrow D \newline h(a,b) = f(g(a,b))$

We can go one step further and compose three compositions.

$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))$

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

$\circ: (\beta \rightarrow \gamma) \times (\alpha \rightarrow \beta) \rightarrow (\alpha \rightarrow \gamma)$

Both parameters are also composition functions therefore the signatures of $\alpha, \beta, \gamma$ are

$\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))$

Therefore the signature of the outcome is

$\alpha \rightarrow \gamma = (y \rightarrow z) \rightarrow (a \rightarrow x \rightarrow y) \rightarrow (a \rightarrow x \rightarrow z)$

Which is the signature of unary-binary-composition function.

As you can see it doesn’t tell you why. It’s like saying $2x$ is the slope of the tangent line of $x^2$ without mentioning derivative.

If you know 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:

$\circ_{hom(x,-)} : (y \rightarrow z) \rightarrow (y^x \rightarrow z^x)$ ###### If you are not familiar with $x^y$ notation, you can just think of it as a function $y \rightarrow x$

And here’s the composition of two function compositions

$\circ_{hom(x,-)} \circ \circ_{hom(a,-)} : (y \rightarrow z) \rightarrow (y^{xa} \rightarrow z^{xa})$ You can construct $h: x\times a \rightarrow z$ universally with $f: y\rightarrow z$ and $g: x\times a \rightarrow y$

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.

(.*) :: (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

25.0
5.0