When you are writing slightly more complex functions I notice that $
is used a lot but I don't have a clue what it does?
$
is infix "application". It's defined as
($) :: (a -> b) -> a -> b
f $ x = f x
-- or
($) f x = f x
-- or
($) = id
It's useful for avoiding extra parentheses: f (g x) == f $ g x
.
A particularly useful location for it is for a "trailing lambda body" like
forM_ [1..10] $ \i -> do
l <- readLine
replicateM_ i $ print l
compared to
forM_ [1..10] (\i -> do
l <- readLine
replicateM_ i (print l)
)
Or, trickily, it shows up sectioned sometimes when expressing "apply this argument to whatever function"
applyArg :: a -> (a -> b) -> b
applyArg x = ($ x)
>>> map ($ 10) [(+1), (+2), (+3)]
[11, 12, 13]
f . g . h $ x
sometimes, which could also be (f . g . h) x
. –
Cominform $
is a bit of a lie at present. GHC actually treats it as syntax so that the runST $ do
idiom works (except in things like sections where it really is a function). It should be just a function, but higher rank types are a problem. –
Mongrelize <$>
is just infix fmap
. It doesn't do anything special as far as I know. –
Cominform (a->b)->a->b
is same as (a->b)->(a->b)
because ->
is right associative. –
Beacham I like to think of the $ sign as a replacement for parenthesis.
For example, the following expression:
take 1 $ filter even [1..10]
-- = [2]
What happens if we don't put the $? Then we would get
take 1 filter even [1..10]
and the compiler would now complain, because it would think we're trying to apply 4 arguments to the take
function, with the arguments being 1 :: Int
, filter :: (a -> Bool) -> [a] -> [a]
, even :: Integral a => a -> Bool
, [1..10] :: [Int]
.
This is obviously incorrect. So what can we do instead? Well, we could put parenthesis around our expression:
(take 1) (filter even [1..10])
This would now reduce to:
(take 1) ([2,4,6,8,10])
which then becomes:
take 1 [2,4,6,8,10]
But we don't always want to be writing parenthesis, especially when functions start getting nested in each other. An alternative is to place the $
sign between where the pair of parenthesis would go, which in this case would be:
take 1 $ filter even [1..10]
$
symbol otherwise the end of the line. –
Clement © 2022 - 2024 — McMap. All rights reserved.