Related
This question already has answers here:
Defining a function by equations with different number of arguments
(3 answers)
Closed 1 year ago.
While trying to define a Haskell function which corresponds to repeated evaluation, I ran into an "Equations give different arities" error. This is my code:
nEvals :: Int -> (a -> a) -> a -> a
nEvals 1 = ($) --equivalent to nEvals 1 f x = f x
nEvals k f = (nEvals (k - 1) f) . f --equivalent to nEvals k f x = nEvals (k - 1) f (f x)
I don't quite understand why Haskell is giving this error, since I'm using pattern matching, not explicitly assigning a value for a given set of inputs. Perhaps Haskell only allows pattern matching on a fixed number of parameters? If so, could someone explain why that decision was made?
You should specify the same number of parameters in all the clauses of the definition of your function. This thus means that you implement this as:
nEvals :: Int -> (a -> a) -> a -> a
nEvals 1 f = f -- added f as parameter
nEvals k f = (nEvals (k - 1) f) . f
we can also reduce the number of parameters with:
nEvals :: Int -> (a -> a) -> a -> a
nEvals 1 = id
nEvals k = (.) =<< nEvals (k - 1)
The Haskell Report section 4.4.3.1 requires it:
A function binding binds a variable to a function value. The general form of a function binding for variable x is:
x p11 … p1k match1
…
x pn1 … pnk matchn
where each pij is a pattern, [...]
Note that all clauses defining a function must be contiguous, and the number of patterns in each clause must be the same.
It doesn't explicitly say why, but it does state that:
Translation: The general binding form for functions is semantically equivalent to the equation (i.e. simple pattern binding):
x = \ x1 … xk -> case (x1, …, xk) of
(p11, …, p1k) match1
…
(pn1, …, pnk) matchn
This translation would not be possible with different numbers of patterns.
It might have been possible to instead define the behavior in terms of e.g.
case (x11, …, x1k) of
(p11, …, p1k) match1
_ -> case (x21, …, x2k) of
(p21, …, p2k) match2
_ -> ...
but it seems like a mess that it's harder for the compiler to work efficiently with, for very little benefit.
What is the difference between the dot (.) and the dollar sign ($)?
As I understand it, they are both syntactic sugar for not needing to use parentheses.
The $ operator is for avoiding parentheses. Anything appearing after it will take precedence over anything that comes before.
For example, let's say you've got a line that reads:
putStrLn (show (1 + 1))
If you want to get rid of those parentheses, any of the following lines would also do the same thing:
putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1
The primary purpose of the . operator is not to avoid parentheses, but to chain functions. It lets you tie the output of whatever appears on the right to the input of whatever appears on the left. This usually also results in fewer parentheses, but works differently.
Going back to the same example:
putStrLn (show (1 + 1))
(1 + 1) doesn't have an input, and therefore cannot be used with the . operator.
show can take an Int and return a String.
putStrLn can take a String and return an IO ().
You can chain show to putStrLn like this:
(putStrLn . show) (1 + 1)
If that's too many parentheses for your liking, get rid of them with the $ operator:
putStrLn . show $ 1 + 1
They have different types and different definitions:
infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)
infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x
($) is intended to replace normal function application but at a different precedence to help avoid parentheses. (.) is for composing two functions together to make a new function.
In some cases they are interchangeable, but this is not true in general. The typical example where they are is:
f $ g $ h $ x
==>
f . g . h $ x
In other words in a chain of $s, all but the final one can be replaced by .
Also note that ($) is the identity function specialised to function types. The identity function looks like this:
id :: a -> a
id x = x
While ($) looks like this:
($) :: (a -> b) -> (a -> b)
($) = id
Note that I've intentionally added extra parentheses in the type signature.
Uses of ($) can usually be eliminated by adding parenthesis (unless the operator is used in a section). E.g.: f $ g x becomes f (g x).
Uses of (.) are often slightly harder to replace; they usually need a lambda or the introduction of an explicit function parameter. For example:
f = g . h
becomes
f x = (g . h) x
becomes
f x = g (h x)
($) allows functions to be chained together without adding parentheses to control evaluation order:
Prelude> head (tail "asdf")
's'
Prelude> head $ tail "asdf"
's'
The compose operator (.) creates a new function without specifying the arguments:
Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'
Prelude> let second = head . tail
Prelude> second "asdf"
's'
The example above is arguably illustrative, but doesn't really show the convenience of using composition. Here's another analogy:
Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"
If we only use third once, we can avoid naming it by using a lambda:
Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"
Finally, composition lets us avoid the lambda:
Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"
The short and sweet version:
($) calls the function which is its left-hand argument on the value which is its right-hand argument.
(.) composes the function which is its left-hand argument on the function which is its right-hand argument.
One application that is useful and took me some time to figure out from the very short description at Learn You a Haskell: Since
f $ x = f x
and parenthesizing the right hand side of an expression containing an infix operator converts it to a prefix function, one can write ($ 3) (4 +) analogous to (++ ", world") "hello".
Why would anyone do this? For lists of functions, for example. Both:
map (++ ", world") ["hello", "goodbye"]
map ($ 3) [(4 +), (3 *)]
are shorter than
map (\x -> x ++ ", world") ["hello", "goodbye"]
map (\f -> f 3) [(4 +), (3 *)]
Obviously, the latter variants would be more readable for most people.
Haskell: difference between . (dot) and $ (dollar sign)
What is the difference between the dot (.) and the dollar sign ($)?. As I understand it, they are both syntactic sugar for not needing to use parentheses.
They are not syntactic sugar for not needing to use parentheses - they are functions, - infixed, thus we may call them operators.
Compose, (.), and when to use it.
(.) is the compose function. So
result = (f . g) x
is the same as building a function that passes the result of its argument passed to g on to f.
h = \x -> f (g x)
result = h x
Use (.) when you don't have the arguments available to pass to the functions you wish to compose.
Right associative apply, ($), and when to use it
($) is a right-associative apply function with low binding precedence. So it merely calculates the things to the right of it first. Thus,
result = f $ g x
is the same as this, procedurally (which matters since Haskell is evaluated lazily, it will begin to evaluate f first):
h = f
g_x = g x
result = h g_x
or more concisely:
result = f (g x)
Use ($) when you have all the variables to evaluate before you apply the preceding function to the result.
We can see this by reading the source for each function.
Read the Source
Here's the source for (.):
-- | Function composition.
{-# INLINE (.) #-}
-- Make sure it has TWO args only on the left, so that it inlines
-- when applied to two functions, even if there is no final argument
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
And here's the source for ($):
-- | Application operator. This operator is redundant, since ordinary
-- application #(f x)# means the same as #(f '$' x)#. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- > f $ g $ h x = f (g (h x))
--
-- It is also useful in higher-order situations, such as #'map' ('$' 0) xs#,
-- or #'Data.List.zipWith' ('$') fs xs#.
{-# INLINE ($) #-}
($) :: (a -> b) -> a -> b
f $ x = f x
Conclusion
Use composition when you do not need to immediately evaluate the function. Maybe you want to pass the function that results from composition to another function.
Use application when you are supplying all arguments for full evaluation.
So for our example, it would be semantically preferable to do
f $ g x
when we have x (or rather, g's arguments), and do:
f . g
when we don't.
... or you could avoid the . and $ constructions by using pipelining:
third xs = xs |> tail |> tail |> head
That's after you've added in the helper function:
(|>) x y = y x
My rule is simple (I'm beginner too):
do not use . if you want to pass the parameter (call the function), and
do not use $ if there is no parameter yet (compose a function)
That is
show $ head [1, 2]
but never:
show . head [1, 2]
A great way to learn more about anything (any function) is to remember that everything is a function! That general mantra helps, but in specific cases like operators, it helps to remember this little trick:
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
and
:t ($)
($) :: (a -> b) -> a -> b
Just remember to use :t liberally, and wrap your operators in ()!
All the other answers are pretty good. But there’s an important usability detail about how ghc treats $, that the ghc type checker allows for instatiarion with higher rank/ quantified types. If you look at the type of $ id for example you’ll find it’s gonna take a function whose argument is itself a polymorphic function. Little things like that aren’t given the same flexibility with an equivalent upset operator. (This actually makes me wonder if $! deserves the same treatment or not )
The most important part about $ is that it has the lowest operator precedence.
If you type info you'll see this:
λ> :info ($)
($) :: (a -> b) -> a -> b
-- Defined in ‘GHC.Base’
infixr 0 $
This tells us it is an infix operator with right-associativity that has the lowest possible precedence. Normal function application is left-associative and has highest precedence (10). So $ is something of the opposite.
So then we use it where normal function application or using () doesn't work.
So, for example, this works:
λ> head . sort $ "example"
λ> e
but this does not:
λ> head . sort "example"
because . has lower precedence than sort and the type of (sort "example") is [Char]
λ> :type (sort "example")
(sort "example") :: [Char]
But . expects two functions and there isn't a nice short way to do this because of the order of operations of sort and .
I think a short example of where you would use . and not $ would help clarify things.
double x = x * 2
triple x = x * 3
times6 = double . triple
:i times6
times6 :: Num c => c -> c
Note that times6 is a function that is created from function composition.
I am able to understand the basics of point-free functions in Haskell:
addOne x = 1 + x
As we see x on both sides of the equation, we simplify it:
addOne = (+ 1)
Incredibly it turns out that functions where the same argument is used twice in different parts can be written point-free!
Let me take as a basic example the average function written as:
average xs = realToFrac (sum xs) / genericLength xs
It may seem impossible to simplify xs, but http://pointfree.io/ comes out with:
average = ap ((/) . realToFrac . sum) genericLength
That works.
As far as I understand this states that average is the same as calling ap on two functions, the composition of (/) . realToFrac . sum and genericLength
Unfortunately the ap function makes no sense whatsoever to me, the docs http://hackage.haskell.org/package/base-4.8.1.0/docs/Control-Monad.html#v:ap state:
ap :: Monad m => m (a -> b) -> m a -> m b
In many situations, the liftM operations can be replaced by uses of ap,
which promotes function application.
return f `ap` x1 `ap` ... `ap` xn
is equivalent to
liftMn f x1 x2 ... xn
But writing:
let average = liftM2 ((/) . realToFrac . sum) genericLength
does not work, (gives a very long type error message, ask and I'll include it), so I do not understand what the docs are trying to say.
How does the expression ap ((/) . realToFrac . sum) genericLength work? Could you explain ap in simpler terms than the docs?
Any lambda term can be rewritten to an equivalent term that uses just a set of suitable combinators and no lambda abstractions. This process is called abstraciton elimination. During the process you want to remove lambda abstractions from inside out. So at one step you have λx.M where M is already free of lambda abstractions, and you want to get rid of x.
If M is x, you replace λx.x with id (id is usually denoted by I in combinatory logic).
If M doesn't contain x, you replace the term with const M (const is usually denoted by K in combinatory logic).
If M is PQ, that is the term is λx.PQ, you want to "push" x inside both parts of the function application so that you can recursively process both parts. This is accomplished by using the S combinator defined as λfgx.(fx)(gx), that is, it takes two functions and passes x to both of them, and applies the results together. You can easily verify that that λx.PQ is equivalent to S(λx.P)(λx.Q), and we can recursively process both subterms.
As described in the other answers, the S combinator is available in Haskell as ap (or <*>) specialized to the reader monad.
The appearance of the reader monad isn't accidental: When solving the task of replacing λx.M with an equivalent function is basically lifting M :: a to the reader monad r -> a (actually the reader Applicative part is enough), where r is the type of x. If we revise the process above:
The only case that is actually connected with the reader monad is when M is x. Then we "lift" x to id, to get rid of the variable. The other cases below are just mechanical applications of lifting an expression to an applicative functor:
The other case λx.M where M doesn't contain x, it's just lifting M to the reader applicative, which is pure M. Indeed, for (->) r, pure is equivalent to const.
In the last case, <*> :: f (a -> b) -> f a -> f b is function application lifted to a monad/applicative. And this is exactly what we do: We lift both parts P and Q to the reader applicative and then use <*> to bind them together.
The process can be further improved by adding more combinators, which allows the resulting term to be shorter. Most often, combinators B and C are used, which in Haskell correspond to functions (.) and flip. And again, (.) is just fmap/<$> for the reader applicative. (I'm not aware of such a built-in function for expressing flip, but it'd be viewed as a specialization of f (a -> b) -> a -> f b for the reader applicative.)
Some time ago I wrote a short article about this: The Monad Reader Issue 17, The Reader Monad and Abstraction Elimination.
When the monad m is (->) a, as in your case, you can define ap as follows:
ap f g = \x -> f x (g x)
We can see that this indeed "works" in your pointfree example.
average = ap ((/) . realToFrac . sum) genericLength
average = \x -> ((/) . realToFrac . sum) x (genericLength x)
average = \x -> (/) (realToFrac (sum x)) (genericLength x)
average = \x -> realToFrac (sum x) / genericLength x
We can also derive ap from the general law
ap f g = do ff <- f ; gg <- g ; return (ff gg)
that is, desugaring the do-notation
ap f g = f >>= \ff -> g >>= \gg -> return (ff gg)
If we substitute the definitions of the monad methods
m >>= f = \x -> f (m x) x
return x = \_ -> x
we get the previous definition of ap back (for our specific monad (->) a). Indeed:
app f g
= f >>= \ff -> g >>= \gg -> return (ff gg)
= f >>= \ff -> g >>= \gg -> \_ -> ff gg
= f >>= \ff -> g >>= \gg _ -> ff gg
= f >>= \ff -> \x -> (\gg _ -> ff gg) (g x) x
= f >>= \ff -> \x -> (\_ -> ff (g x)) x
= f >>= \ff -> \x -> ff (g x)
= f >>= \ff x -> ff (g x)
= \y -> (\ff x -> ff (g x)) (f y) y
= \y -> (\x -> f y (g x)) y
= \y -> f y (g y)
The Simple Bit: fixing liftM2
The problem in the original example is that ap works a bit differently from the liftM functions. ap takes a function wrapped up in a monad, and applies it to an argument wrapped up in a monad. But the liftMn functions take a "normal" function (one which is not wrapped up in a monad) and apply it to argument(s) that are wrapped up in monads.
I'll explain more about what that means below, but the upshot is that if you want to use liftM2, then you have to pull (/) out and make it a separate argument at the beginning. (So in this case (/) is the "normal" function.)
let average = liftM2 ((/) . realToFrac . sum) genericLength -- does not work
let average = liftM2 (/) (realToFrac . sum) genericLength -- works
As posted in the original question, calling liftM2 should involve three agruments: liftM2 f x1 x2. Here the f is (/), x1 is (realToFrac . sum) and x2 is genericLength.
The version posted in the question (the one which doesn't work) was trying to call liftM2 with only two arguments.
The explanation
I'll build this up in a few stages. I'll start with some specific values, and build up to a function that can take any set of values. Jump to the last section for the TL:DR
In this example, lets assume the list of numbers is [1,2,3,4]. The sum of these numbers is 10, and the length of the list is 4. The average is 10/4 or 2.5.
To shoe-horn this into the right form for ap, we're going to break this into a function, an input, and a result.
ourFunction = (10/) -- "divide 10 by"
ourInput = 4
ourResult = 2.5
Three kinds of Function Application
ap and listM both involve monads. At this point in the explanation, you can think of a monad as something that a value can be "wrapped up in". I'll give a better definition below.
Normal function application applies a normal function to a normal input. liftM applies a normal function to an input wrapped in a monad, and ap applies a function wrapped in a monad to an input wrapped in a monad.
(10/) 4 -- returns 2.5
liftM (10/) monad(4) -- returns monad(2.5)
ap monad(10/) monad(4) -- returns monad(2.5)
(Note that this is pseudocode. monad(4) is not actually valid Haskell).
(Note that liftM is a different function from liftM2, which was used earlier. liftM takes a function and only one argument, which is a better fit for the pattern i'm describing.)
In the average function defined above, the monads were functions, but "functions-as-monads" can be hard to talk about, so I'll start with simpler examples.
So what's a monad?
A better description of a monad is "something which contains a value, or produces a value, or which you can somehow extract a value from, but which also has something more complicated going on."
That's a really vague description, but it kind of has to be, because the "something more complicated" can be a lot of different things.
Monads can be confusing, but the point of them is that when you use monad operations (like ap and liftM) they will take care of the "something more complicated" for you, so you can just concentrate on the values.
That's probably still not very clear, so let's do some examples:
The Maybe monad
ap (Just (10/)) (Just 4) -- result is (Just 2.5)
One of the simplest monads is 'Maybe'. The value is whatever is contained inside a Just. So if we call ap and give it (Just ourFunction) and (Just ourInput) then we get back (Just ourResult).
The "something more complicated" is the fact that there might not be a value there at all, and you have to allow for the Nothing case.
As mentioned, the point of using a function like ap is that it takes care of these extra complications for us. With the Maybe monad, ap handles this by returning Nothing if either the Maybe-function or the Maybe-input were Nothing.
ap (Just (10/)) Nothing -- result is Nothing
ap Nothing (Just 4) -- result is Nothing
The List Monad
ap [(10/)] [4] -- result is [2.5]
With the list Monad, the value is whatever is inside the list. So ap [ourfunction] [ourInput] returns [ourResult].
The "something more complicated" is that there may be more than one thing inside the list (or exactly one thing, or nothing at all).
With lists, that means ap takes a list of zero or more functions, and a list of zero or more inputs. It handles that by returning a list of zero or more results: one result for every possible combination of function and input.
ap [(10/), (100/)] [5,4,2] -- result is [2.0, 2.5, 5.0, 20.0, 25.0, 50.0]
Functions as Monads
A function like genericLength is considered a Monad because it has a value (the function's output), and it has a "something more complicated" (the fact that you have to supply an input before you can get the value).
This is where it gets a little confusing, because we're dealing with multiple functions, multiple inputs, and multiple results. It is all well defined, it's just hard to describe, so we have to be careful with our terminology.
Lets start with the list [1,2,3,4], and call that our "original input". That's the list we're trying to find the average of. It's the xs argument in the original average function.
If we give our original input ([1,2,3,4]) to genericLength then we get a value of '4'.
Our other function is ((/) . realToFrac . sum). It takes our list [1,2,3,4] and finds the sum (10), turns that into a fractional value, and then feeds it as the first argument to (/). The result is an incomplete division function that is waiting for another argument. ie it takes [1,2,3,4] as an input, and produces (10/) as its output.
This all fits with the way ap is defined for functions. With functions, ap takes two things. The first is a function that reads the original input and produces a new function. The second is a function that reads the original input and produces a new input. The final result is a function that takes the original input, and returns the same thing you would get if you applied the new function to the new input.
You might have to read that a few times to make sense of it. Alternatively, here it is in pseudocode:
average =
ap
(functionThatTakes [1,2,3,4] and returns "(10/)" )
(functionThatTakes [1,2,3,4] and returns " 4 " )
-- which means:
average =
(functionThatTakes [1,2,3,4] and returns "2.5" )
If you compare this to the simpler examples above, you'll see that it still has our function (10/), our input 4 and our result 2.5. And each of them is once again wrapped up in the "something more complicated". In this case, the "something more complicated" is the "function that takes [1,2,3,4] and returns...".
Of course, since they're functions, they don't have to take [1,2,3,4] as their input. If they took a different list of integers (eg [1,2,3,4,5]) then we would get different results (e.g. new function: (15/), new input 5 and new value 3).
Other examples
minPlusMax = ap ((+) . minimum) maximum
-- a function that adds the minimum element of a list, to the maximum element
upperAndLower = ap ((,) . toUpper) toLower
-- a function that takes a Char and returns a tuple, with the upper case and lower case versions of a character
These could all also be defined using liftM2.
average = liftM2 (/) sum genericLength
minPlusMax = liftM2 (+) minimum maximum
upperAndLower = liftM2 (,) toUpper toLower
While I understand a little about currying in the mathematical sense, partially
applying an infix function was a new concept which I discovered after diving
into the book Learn You a Haskell for Great Good.
Given this function:
applyTwice :: (a -> a) -> a -> a
applyTwice f x = f (f x)
The author uses it in a interesting way:
ghci> applyTwice (++ [0]) [1]
[1,0,0]
ghci> applyTwice ([0] ++) [1]
[0,0,1]
Here I can see clearly that the resulting function had different parameters
passed, which would not happen by normal means considering it is a curried
function (would it?). So, is there any special treatment on infix sectioning by
Haskell? Is it generic to all infix functions?
As a side note, this is my first week with Haskell and functional programming,
and I'm still reading the book.
Yes, you can partially apply an infix operator by specifying either its left or right operand, just leaving the other one blank (exactly in the two examples you wrote).
So, ([0] ++) is the same as (++) [0] or \x -> [0] ++ x (remember you can turn an infix operator into a standard function by means of parenthesis), while (++ [0]) equals to \x -> x ++ [0].
It is useful to know also the usage of backticks, ( `` ), that enable you to turn any standard function with two arguments in an infix operator:
Prelude> elem 2 [1,2,3]
True
Prelude> 2 `elem` [1,2,3] -- this is the same as before
True
Prelude> let f = (`elem` [1,2,3]) -- partial application, second operand
Prelude> f 1
True
Prelude> f 4
False
Prelude> let g = (1 `elem`) -- partial application, first operand
Prelude> g [1,2]
True
Prelude> g [2,3]
False
Yes, this is the section syntax at work.
Sections are written as ( op e ) or ( e op ), where op is a binary operator and e is an expression. Sections are a convenient syntax for partial application of binary operators.
The following identities hold:
(op e) = \ x -> x op e
(e op) = \ x -> e op x
All infix operators can be used in sections in Haskell - except for - due to strangeness with unary negation. This even includes non-infix functions converted to infix by use of backticks. You can even think of the formulation for making operators into normal functions as a double-sided section:
(x + y) -> (+ y) -> (+)
Sections are (mostly, with some rare corner cases) treated as simple lambdas. (/ 2) is the same as:
\x -> (x / 2)
and (2 /) is the same as \x -> (2 / x), for an example with a non-commutative operator.
There's nothing deeply interesting theoretically going on here. It's just syntactic sugar for partial application of infix operators. It makes code a little bit prettier, often. (There are counterexamples, of course.)
What is the difference between the dot (.) and the dollar sign ($)?
As I understand it, they are both syntactic sugar for not needing to use parentheses.
The $ operator is for avoiding parentheses. Anything appearing after it will take precedence over anything that comes before.
For example, let's say you've got a line that reads:
putStrLn (show (1 + 1))
If you want to get rid of those parentheses, any of the following lines would also do the same thing:
putStrLn (show $ 1 + 1)
putStrLn $ show (1 + 1)
putStrLn $ show $ 1 + 1
The primary purpose of the . operator is not to avoid parentheses, but to chain functions. It lets you tie the output of whatever appears on the right to the input of whatever appears on the left. This usually also results in fewer parentheses, but works differently.
Going back to the same example:
putStrLn (show (1 + 1))
(1 + 1) doesn't have an input, and therefore cannot be used with the . operator.
show can take an Int and return a String.
putStrLn can take a String and return an IO ().
You can chain show to putStrLn like this:
(putStrLn . show) (1 + 1)
If that's too many parentheses for your liking, get rid of them with the $ operator:
putStrLn . show $ 1 + 1
They have different types and different definitions:
infixr 9 .
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(f . g) x = f (g x)
infixr 0 $
($) :: (a -> b) -> a -> b
f $ x = f x
($) is intended to replace normal function application but at a different precedence to help avoid parentheses. (.) is for composing two functions together to make a new function.
In some cases they are interchangeable, but this is not true in general. The typical example where they are is:
f $ g $ h $ x
==>
f . g . h $ x
In other words in a chain of $s, all but the final one can be replaced by .
Also note that ($) is the identity function specialised to function types. The identity function looks like this:
id :: a -> a
id x = x
While ($) looks like this:
($) :: (a -> b) -> (a -> b)
($) = id
Note that I've intentionally added extra parentheses in the type signature.
Uses of ($) can usually be eliminated by adding parenthesis (unless the operator is used in a section). E.g.: f $ g x becomes f (g x).
Uses of (.) are often slightly harder to replace; they usually need a lambda or the introduction of an explicit function parameter. For example:
f = g . h
becomes
f x = (g . h) x
becomes
f x = g (h x)
($) allows functions to be chained together without adding parentheses to control evaluation order:
Prelude> head (tail "asdf")
's'
Prelude> head $ tail "asdf"
's'
The compose operator (.) creates a new function without specifying the arguments:
Prelude> let second x = head $ tail x
Prelude> second "asdf"
's'
Prelude> let second = head . tail
Prelude> second "asdf"
's'
The example above is arguably illustrative, but doesn't really show the convenience of using composition. Here's another analogy:
Prelude> let third x = head $ tail $ tail x
Prelude> map third ["asdf", "qwer", "1234"]
"de3"
If we only use third once, we can avoid naming it by using a lambda:
Prelude> map (\x -> head $ tail $ tail x) ["asdf", "qwer", "1234"]
"de3"
Finally, composition lets us avoid the lambda:
Prelude> map (head . tail . tail) ["asdf", "qwer", "1234"]
"de3"
The short and sweet version:
($) calls the function which is its left-hand argument on the value which is its right-hand argument.
(.) composes the function which is its left-hand argument on the function which is its right-hand argument.
One application that is useful and took me some time to figure out from the very short description at Learn You a Haskell: Since
f $ x = f x
and parenthesizing the right hand side of an expression containing an infix operator converts it to a prefix function, one can write ($ 3) (4 +) analogous to (++ ", world") "hello".
Why would anyone do this? For lists of functions, for example. Both:
map (++ ", world") ["hello", "goodbye"]
map ($ 3) [(4 +), (3 *)]
are shorter than
map (\x -> x ++ ", world") ["hello", "goodbye"]
map (\f -> f 3) [(4 +), (3 *)]
Obviously, the latter variants would be more readable for most people.
Haskell: difference between . (dot) and $ (dollar sign)
What is the difference between the dot (.) and the dollar sign ($)?. As I understand it, they are both syntactic sugar for not needing to use parentheses.
They are not syntactic sugar for not needing to use parentheses - they are functions, - infixed, thus we may call them operators.
Compose, (.), and when to use it.
(.) is the compose function. So
result = (f . g) x
is the same as building a function that passes the result of its argument passed to g on to f.
h = \x -> f (g x)
result = h x
Use (.) when you don't have the arguments available to pass to the functions you wish to compose.
Right associative apply, ($), and when to use it
($) is a right-associative apply function with low binding precedence. So it merely calculates the things to the right of it first. Thus,
result = f $ g x
is the same as this, procedurally (which matters since Haskell is evaluated lazily, it will begin to evaluate f first):
h = f
g_x = g x
result = h g_x
or more concisely:
result = f (g x)
Use ($) when you have all the variables to evaluate before you apply the preceding function to the result.
We can see this by reading the source for each function.
Read the Source
Here's the source for (.):
-- | Function composition.
{-# INLINE (.) #-}
-- Make sure it has TWO args only on the left, so that it inlines
-- when applied to two functions, even if there is no final argument
(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g = \x -> f (g x)
And here's the source for ($):
-- | Application operator. This operator is redundant, since ordinary
-- application #(f x)# means the same as #(f '$' x)#. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- > f $ g $ h x = f (g (h x))
--
-- It is also useful in higher-order situations, such as #'map' ('$' 0) xs#,
-- or #'Data.List.zipWith' ('$') fs xs#.
{-# INLINE ($) #-}
($) :: (a -> b) -> a -> b
f $ x = f x
Conclusion
Use composition when you do not need to immediately evaluate the function. Maybe you want to pass the function that results from composition to another function.
Use application when you are supplying all arguments for full evaluation.
So for our example, it would be semantically preferable to do
f $ g x
when we have x (or rather, g's arguments), and do:
f . g
when we don't.
... or you could avoid the . and $ constructions by using pipelining:
third xs = xs |> tail |> tail |> head
That's after you've added in the helper function:
(|>) x y = y x
My rule is simple (I'm beginner too):
do not use . if you want to pass the parameter (call the function), and
do not use $ if there is no parameter yet (compose a function)
That is
show $ head [1, 2]
but never:
show . head [1, 2]
A great way to learn more about anything (any function) is to remember that everything is a function! That general mantra helps, but in specific cases like operators, it helps to remember this little trick:
:t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c
and
:t ($)
($) :: (a -> b) -> a -> b
Just remember to use :t liberally, and wrap your operators in ()!
All the other answers are pretty good. But there’s an important usability detail about how ghc treats $, that the ghc type checker allows for instatiarion with higher rank/ quantified types. If you look at the type of $ id for example you’ll find it’s gonna take a function whose argument is itself a polymorphic function. Little things like that aren’t given the same flexibility with an equivalent upset operator. (This actually makes me wonder if $! deserves the same treatment or not )
The most important part about $ is that it has the lowest operator precedence.
If you type info you'll see this:
λ> :info ($)
($) :: (a -> b) -> a -> b
-- Defined in ‘GHC.Base’
infixr 0 $
This tells us it is an infix operator with right-associativity that has the lowest possible precedence. Normal function application is left-associative and has highest precedence (10). So $ is something of the opposite.
So then we use it where normal function application or using () doesn't work.
So, for example, this works:
λ> head . sort $ "example"
λ> e
but this does not:
λ> head . sort "example"
because . has lower precedence than sort and the type of (sort "example") is [Char]
λ> :type (sort "example")
(sort "example") :: [Char]
But . expects two functions and there isn't a nice short way to do this because of the order of operations of sort and .
I think a short example of where you would use . and not $ would help clarify things.
double x = x * 2
triple x = x * 3
times6 = double . triple
:i times6
times6 :: Num c => c -> c
Note that times6 is a function that is created from function composition.