To begin with, we have the lovely definition
x = 1 : map (2*) x
which by itself is a bit mind-bending if you've never seen it before. Anyway it's a fairly standard trick of laziness and recursion. Now, we'll get rid of the explicit recursion using fix
, and point-free-ify.
x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))
The next thing we're going to do is expand the :
section and make the map
needlessly complex.
x = fix ((:) 1 . (map . (*) . (*2)) 1)
Well, now we have two copies of that constant 1
. That will never do, so we'll use the reader applicative to de-duplicate that. Also, function composition is a bit rubbish, so let's replace that with (<$>)
wherever we can.
x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)
Next up: that call to map
is much too readable. But there's nothing to fear: we can use the monad laws to expand it a bit. In particular, fmap f x = x >>= return . f
, so
map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x
We can point-free-ify, replace (.)
with (<$>)
, and then add some spurious sections:
map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)
Substituting this equation in our previous step:
x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)
Finally, you break your spacebar and produce the wonderful final equation
x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)