I was bored one day and wanted to exercise my brain, so I decided to do the 99 Haskell Problems but restricted myself to doing them in point-free style. A problem that seems to
There are a few basic idiomatic combinators which pop up repeatedly, and are reimplemented with various higher concepts and libraries, but which are essentially very simple. Names may vary, and some are implementable in terms of others:
fork (f,g) x = (f x, g x) -- == (f &&& g)
prod (f,g) x = (f $ fst x, g $ snd x) -- == (f *** g)
pmap f (x,y) = (f x, f y) -- == (f *** f)
dup x = (x,x)
etc. Of course uncurry f (x,y) == f x y
gets used a lot with these, too.
&&&
and ***
are defined in Control.Arrow
, as well as first
and second
. Then prod (f,id) == first f
, prod(id,g) == second g
etc. etc.
So your foobar
becomes
foobar = (\(a,b)->[a,b]) . fork (id,reverse)
= (\(a,b)->[a,b]) . (id &&& reverse)
= (\(a,b)->[a,b]) . (id *** reverse) . dup
= join $ curry ( (\(a,b)->[a,b]) . second reverse)
For the last one you need to also import Control.Monad
and Control.Monad.Instances
. See also this question.
late edit: also, using Control.Applicative
as hinted in answer by ertes,
= (:) <*> ((:[]) . reverse)