Haskell DISCUSSION

Haskell: what is the difference between the dot (.) and dollar ($) operators, and when do I use each?

Started by rehanakhtar Haskell function compositiondollar operatoroperator precedencepoint-free stylefunction application
4 replies 248 views 5 participants
Latest activity · 30 Sep 2026

Haskell: what is the difference between the dot (.) and dollar ($) operators, and when do I use each?

rehanakhtar Haskell Forum
#1

I see both . and $ used to get rid of parentheses. putStrLn (show (length xs)) can apparently be written as putStrLn $ show $ length xs or as putStrLn . show . length $ xs, but my attempt putStrLn . show . length xs does not compile.

What does each operator actually do, and how do I know which one to reach for?

Community replies 4

Re: Haskell: what is the difference between the dot (.) and dollar ($) operators, and when do I use each?

#2

$ is function application as an operator: f $ x = f x, with type (a -> b) -> a -> b. It does nothing that a space does not do; its whole value is its precedence. Ordinary application binds tighter than any operator, while $ has the lowest precedence (0) and associates to the right. So everything to the right of a $ is evaluated as one argument: putStrLn $ show $ length xs parses as putStrLn (show (length xs)).

Re: Haskell: what is the difference between the dot (.) and dollar ($) operators, and when do I use each?

#3

. is function composition: (f . g) x = f (g x), with type (b -> c) -> (a -> b) -> a -> c. It takes two functions and returns a new function; no argument is involved yet. It has high precedence (9), still lower than plain application.

That explains your error. putStrLn . show . length xs parses as putStrLn . show . (length xs), and length xs is an Int, not a function, so it cannot be composed. Either compose first and apply once, (putStrLn . show . length) xs, or use $ for the final application: putStrLn . show . length $ xs.

Re: Haskell: what is the difference between the dot (.) and dollar ($) operators, and when do I use each?

#4

In practice: use . to build a pipeline of functions, and $ to feed the pipeline its argument. For example sum . map (*2) . filter even $ [1..10] keeps 2, 4, 6, 8, 10, doubles them and adds them up, giving 60. Reading right to left gives the order of the steps.

Composition alone lets you define functions without naming the argument: countWords = length . words, so countWords "to be or not" is 4. With $ you would have to write countWords s = length $ words s.

Re: Haskell: what is the difference between the dot (.) and dollar ($) operators, and when do I use each?

#5

Because $ is an ordinary function, it can be passed around and sectioned. map ($ 3) [(+1), (*2), subtract 1] applies every function in the list to 3 and gives [4, 6, 2]. zipWith ($) fs xs applies a list of functions to a list of arguments pairwise.

There is also a strict variant, f $! x, which evaluates x to weak head normal form before calling f, and & from Data.Function, which is $ with the arguments flipped, so that [1..10] & filter even & sum reads left to right and gives 30.

TEP COMMUNITY