Hemanth.HM

A Computer Polyglot, CLI + WEB ♥'r.

$ in Haskell

| Comments

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 relves:

1
2
Prelude> :t ($)
($) :: (a -> b) -> a -> b
1
($) :: 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:

1
take 5 (reverse (filter odd [1..10]))

We can re-write it as:

1
take 5 $ reverse $ filter odd $ [1..10]

It gets interesting with the function composition operator .

1
2
Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

We can re-write the $ expression to:

1
take 5 . reverse . filter odd $ [1..10]

or

1
(take 5 . reverse . filter odd) [1..10]

Another example would be using the $ and . with interact.

1
2
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:

1
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)

1
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)

Comments