Let's try to decode this pointless style obfuscation:
fmap fmap (,) <*> Just . reverse $ "stackoverflow"
First step: how this is parsed? Well, $
has low precedence, so it's
(fmap fmap (,) <*> Just . reverse) $ "stackoverflow"
Also, I guess that the infix <*>
has a lower precedence than .
(one could check using the documentation or :i
in GHCi). So, we get
((fmap fmap (,)) <*> (Just . reverse)) $ "stackoverflow"
Let's beta-reduce the $
((fmap fmap (,)) <*> (Just . reverse)) "stackoverflow"
So, the result of <*>
is a function. This means that we are working in the (->) a
applicative. There, (<*>) = \x y z -> x z (y z)
AKA the S combinator from lambda calculus. We can beta-reduce that:
(\z -> (fmap fmap (,)) z ((Just . reverse) z)) "stackoverflow"
More betas, removing parentheses when we can:
fmap fmap (,) "stackoverflow" ((Just . reverse) "stackoverflow")
More simplification:
fmap fmap (,) "stackoverflow" (Just (reverse "stackoverflow"))
fmap fmap (,) "stackoverflow" (Just "wolfrevokcats")
Now, the fmap fmap (,)
part. The (,)
argument is a function, so this means that the first fmap
is working in the (->) a
functor. There, fmap = (.)
. So, it's just obfuscation for
(.) fmap (,) "stackoverflow" (Just "wolfrevokcats")
(fmap . (,)) "stackoverflow" (Just "wolfrevokcats")
(fmap ((,) "stackoverflow")) (Just "wolfrevokcats")
fmap ((,) "stackoverflow") (Just "wolfrevokcats")
Now, the second argument of fmap
is of type Maybe String
, so the fmap
is working in the Maybe
functor. There, fmap f (Just x) = Just (f x)
. We get
Just (((,) "stackoverflow") "wolfrevokcats")
Just ((,) "stackoverflow" "wolfrevokcats")
Just ("stackoverflow", "wolfrevokcats")
Conclusion: pointless code is often pointless. To decode this snippet we had to run the type inferer in our head, recall three specific instances (even if they are pretty standard), and cope with precedence. No one should ever use this style except for deliberate obfuscation. (Surely not as a hiring puzzle!)