P.S: This is a cross post from h3manth.com.
Function composition plays a very important role in functional programming and in haskell things get better with the $
operator.
$
AKA Application operator
helps us in avoiding parentheses during function, a quick type check reveals:
Prelude> :t ($)
($) :: (a -> b) -> a -> b
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b infixr 0
That implies (f x)
is same as (f $ x)
but it helps us in rewriting f (g (h x))
as f $ g $ h $ x
So, say we have:
take 5 (reverse (filter odd [1..10]))
We can re-write it as:
take 5 $ reverse $ filter odd $ [1..10]
It gets interesting with the function composition operator .
Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
We can re-write the $
expression to:
take 5 . reverse . filter odd $ [1..10]
or
(take 5 . reverse . filter odd) [1..10]
Another example would be using the $
and .
with interact
.
Prelude> :t (interact)
(interact) :: (String -> String) -> IO ()
^ Input from the standard input device is passed to this function as its argument, and the resulting string is output on the standard output device.
Say, we need to accept multiple inputs from the standard input and add them up, we could do it as:
main = interact $ show . sum . map read . words
If we are trying the same in Prelude
, you must use lines
with it. (Better not to use interact
in GHCi
)
Prelude> interact $ show . sum . map read . words . head . lines
So, the thing to remeber is:
f $ x = f x
(f . g) x = f (g x)