join (,) 9

join (,) 9

What does this do? On its own, not much - in fact you just get:

(9,9)

(9,9)

...which you'd have been much better off typing in yourself. Where it can come-in handy though is when writing code in a pointfree style if you have a need to duplicate an anonymous value into both parts of a pair:

functionWhichTakesAPair . join (,) . functionWhichProducesASingleValue

functionWhichTakesAPair . join (,) . functionWhichProducesASingleValue

Anyway, how / why does this construct work....?

The

`(,)`is just the standard data constructor for a 2-tuple, a pair. (This constructor has type

`a -> b -> (a,b)`so you can always write

`(,) 9 9`as an alternative notation for

`(9,9)`if you wish).

The

`join`is the standard function

`:: Monad m => m (m a) -> m a`we know from monadic programming (Control.Monad). But this just raises the question of how it can make sense to apply it to

`(,)`which as we've seen is a function of type

`a -> b -> (a,b)`.

The answer is of course that this function may be considered to be of type

`m (m a)`. This is because

`Control.Monad.Instances`declares any partially applied function (eg

`a -> ...`) to be a monad (the type

`a`can be seen as representing an encapsulated environment which is threaded through by the monadic bind). This then means that a function of two arguments (such as

`(,)`) can be seen as having type

`m (m a)`which is just what we need to be able to apply

`join`. The net result is that the single argument of the resulting function (

`join (,)`) is passed in twice as desired.

This of course generalises to functions other than

`(,)`- whenever we use

`join f`where

`f`is a function of two arguments, we end up with a function of one argument which is passed into

`f`twice.