What is the 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.
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). Eg: f $ gx
becomes f (gx)
.
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)
Hope this helps!
链接地址: http://www.djcxy.com/p/33162.html上一篇: CPP扩展和Haskell中的多行文字
下一篇: 有什么区别。 (点)和$(美元符号)?