In Haskell, I often write expressions with $'s. I find it quite natural and readable, but I sometimes read it is bad form and do not understand why it should be.
The following are all good form:
foo = bar . baz . quux
foo x = bar . baz . quux $ x
foo x = (bar . baz . quux) x
foo x = bar (baz (quux x))
I've put them in rough order of my preference, though as always taste varies, and context may demand a different choice. I've also occasionally seen
foo = bar
. baz
. quux
when each of the bar
, baz
, and quux
subexpressions are long. The following is bad form:
foo x = bar $ baz $ quux $ x
There are two reasons this is less preferable. First, fewer subexpressions can be copied and pasted into an auxiliary definition during refactoring; with all ($)
operators, only subexpressions that include the x
argument are valid refactorings, whereas with (.)
and ($)
operators even subexpressions like bar . baz
or baz . quux
can be pulled out into a separate definition.
The second reason to prefer (.)
is in anticipation of a possible change to the fixity of ($)
; currently, ($)
is infixr
, meaning it associates to the right, like so:
foo x = bar $ (baz $ (quux $ x))
However, ($)
would be useful in more expressions if it were infixl
; for example, something like
foo h = f (g x) (h y)
foo h = f $ g x $ h y
foo h = (f $ g x) $ h y
...which currently cannot be expressed without parentheses. The "bad form" example, when parsed with an infixl
application, would be
foo x = ((bar $ baz) $ quux) $ x
which means something significantly different. So, future-proof your code by avoiding this form.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With