Square is a monad join of a function

Afsal Thaj
2 min readOct 18, 2020

How do you implement square (or double) using Monads?

Quite simple: Use the monad instance of a function and then `join` on a function that returns a function.

How on earth does that work?

You know the signature of Monad join.

join :: Monad f => f (f a) -> f a
join ffa = ffa >>= id

Consider data Optional a = Full a | Empty has a monad instance. This implies:

>> join (Full (Full 1))
Full 1

In this case,fis Optional, and ffais Full (Full 1)

When you replace Optionalto be a function f: t -> a, then ffais
f: t -> ( t -> a ).

As an example :

 >> ffa = \x -> (\y -> x * y)
>> ffa 2 3
6
>>

ffa = \x -> (\y -> x * y)) is same as ffa = (*)

Thinking along the same lines, calling joinon ffato return fameans converting t-> (t -> a) to t -> a

Let’s do that:

>> :type (join (*))
(join ffa) :: Num a => a -> a

join (*) returns a function Int -> Int effectively.

>> join (*) 10
100

This implies:

>> square = join (*)
>> double = join (+)

Yea, that was more of a fun. But you can sort of guess that monad instance of a function (->) tinvolves passing the same argument twice to a binary function. I will explain this blog with some Scala later , although I found it a little less intuitive considering I cannot write join(*) or (*).join after the required imports from cats/scalaz. But it will still be a good exercise.

--

--

Afsal Thaj

A software engineer, traveller, fitness trainer, hiker, skydiver and I write at times. https://twitter.com/afsalt2