DEV Community

hemanth.hm
hemanth.hm

Posted on

$ in haskell

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
Enter fullscreen mode Exit fullscreen mode
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b infixr 0
Enter fullscreen mode Exit fullscreen mode

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]))
Enter fullscreen mode Exit fullscreen mode

We can re-write it as:

take 5 $ reverse $ filter odd $ [1..10]
Enter fullscreen mode Exit fullscreen mode

It gets interesting with the function composition operator .

Prelude> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
Enter fullscreen mode Exit fullscreen mode

We can re-write the $ expression to:

take 5 . reverse . filter odd $ [1..10]
Enter fullscreen mode Exit fullscreen mode

or

(take 5 . reverse . filter odd) [1..10]
Enter fullscreen mode Exit fullscreen mode

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

Prelude> :t (interact)
(interact) :: (String -> String) -> IO ()
Enter fullscreen mode Exit fullscreen mode

^ 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 
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

So, the thing to remeber is:

  • f $ x = f x

  • (f . g) x = f (g x)

Top comments (0)