Treating "$" as function application - haskell

I encountered this example while reading Learn You a Haskell for Great Good.
ghci> map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
I don't quite see how to treat $ as function application. Does that mean $ is an operator? But if so, how it will be nested with + or * in the example? I tried $ 3 4+, $ 4 + 3, but both raised parse error on input ‘$’. How to think of an expression like this in functional programming context?

$ is indeed an operator, defined as:
f $ x = f x
-- or equivalently:
($) f x = f x
Your expression above is equivalent (by the definition of map) to:
[($ 3) (4 +), ($ 3) (10 *), ($ 3) sqrt]
The parentheses in ($ 3) and (4 +) are not optional. They're part of what's called an operator section. Basically, there are four ways you can use an infix operator (such as +):
Between two arguments:
x + y
Only giving the first argument:
(x +)
-- like \y -> x + y
Only giving the second argument:
(+ y)
-- like \x -> x + y
No arguments:
(+)
-- like \x y -> x + y
($ 3) f evaluates to f $ 3 evaluates to f 3.
($ 3) (4 +) evaluates to (4 +) $ 3 evaluates to (4 +) 3 evaluates to 4 + 3 evaluates to 7.

Related

Haskell: Understanding the map function when used with lambda function

I have the following two Haskell expressions:
map (\f x -> f x 5) [(-),(+),(*)]
map (\f x -> f 5 x) [(-),(+),(*)]
And I'm trying to figure out whether either expression above is equivalent to the following expression:
map ($ 5) [(-),(+),(*)]
I am trying to understand what the difference between the first two expressions is.
Since for both expressions, there is only one parameter passed to the lambda function (e.g. the operator), the function will be partially applied.
Is it correct to say that the elements in the result list from the first expression will be:
(1) - x 5 = (- x) 5
(2) + x 5 = (+ x) 5
(3) * x 5 = (* x) 5
And for the second expression:
(1) - 5 x = (- 5) x
(2) + 5 x = (+ 5) x
(3) * 5 x = (* 5) x
However, I don't think that either expression is equivalent to map ($ 5) [(-),(+),(*)]. This is because (- x) 5 (where x is a number) gives an error in GHCI and is an invalid expression. Similarly (- 5) x also gives an error.
On the other hand, map ($5) [(-)], results in a function that takes a number and subtracts it from 5.
Is this reasoning correct? Any insights are appreciated.
(- 5) 5 gives out an error because prefix minus is a special case in the language syntax: (- 5) means minus five, the number, and not a function that subtracts five (see also: Currying subtraction). That being so, I will focus on the (+) case, which is not exceptional.
In your second expression, map (\f x -> f 5 x) [(-),(+),(*)], the second element of the result list will be:
(\f x -> f 5 x) (+)
When evaluating such a thing by hand, it is important to be careful to not mix up prefix, infix and sectioned uses of operators. Application here gives out...
\x -> (+) 5 x -- Prefix syntax (note the parentheses around the operator)
... which is equivalent to...
\x -> 5 + x -- Infix syntax
... and to:
\x -> (5 +) x -- Left section
\x -> (+ x) 5 -- Right section
(5 +) -- Left section, pointfree
So the sections, which are patterned after infix usage of the operators, should be the other way around relative to your question. As for map ($ 5) [(-),(+),(*)], it is equivalent to map (\f x -> f 5 x) [(-),(+),(*)], your second expression. You can confirm that by using the fact that ($) f x = f x to figure out what the ($ 5) right section is.

Confusion about the $ operator and parentheses

I'm working my way through the first haskell book and struggle with the $ operator:
The following line works:
map (>= 16) . take 5 $ iterate (\x -> x^2) 2
However, the following doesn't:
map (>= 16) . take 5 (iterate (\x -> x^2) 2)
Possible cause: `take' is applied to too many arguments
I don't see the problem here. take takes an int and a list. To my understanding, I provided both arguments.
What do I have to do if I want to avoid the $ operator?
The ($) :: (a -> b) -> a -> b operator is a function that simply has a the lowest priority (infixr 0, only ($!) and seq have the same priority). As a result:
map (>= 16) . take 5 $ iterate (\x -> x^2) 2
is equivalent to:
(map (>= 16) . take 5) (iterate (\x -> x^2) 2)
so also with brackets for the left operand as well.
It is actually a nice thing about Haskell that you can use operators as a grouping mechanism: ($) is simply defined as ($) f x = f x, but because of the fact that it is an operator, it can be used as a way to avoid brackets.

How is $ used in higher order functions ? [duplicate]

This question already has answers here:
Why is `($ 4) (> 3)` equivalent to `4 > 3`?
(3 answers)
Closed 7 years ago.
This concerns an example encountered in Learn you a Haskell for Great Good, namely this one :
ghci> map ($ 3) [(4+), (10*), (^2), sqrt]
I'm trying to understand it but it makes no sense to me. Of course, the list of functions will be applied to the input (number 3) but I don't see how the $ operator helps. I'm trying to trace the order of application of things (if there's a haskell IDE with a step through compiler please let me know) and can't understand how $ being right associative allows flipping the function application, ie when I see map like this
map fun [1, 2 .. n]
I imagine the following happening to form the output list
fun 1
fun 2
.
.
fun n
but for the example at hand, how is this of meaning :
$3 4+
how is this of meaning :
$3 4+
That's not actually of meaning, indeed. But that's not what it simplifies to! It simplifies to
($3) (4+)
These things are operator sections.
($ 3) ≡ \x -> x $ 3
(4+) ≡ \x -> 4 + x
(10*) ≡ \x -> 10*x
(^2) ≡ \x -> x^2
so
($3) (4+) ≡ (\f -> f $ 3) (\y -> 4 + y)
≡ (\y -> 4 + y) $ 3
≡ (\y -> 4 + y) 3
≡ 4 + 3
Perhaps it's easier to understand if you visualise the “holes”:
map (□ $ 3) [(4+□), (10*□), (□^2), sqrt □]
≡ [(4+□) $ 3, (10*□) $ 3, (□^2) $ 3, (sqrt □) $ 3]
≡ [(4+3), (10*3), (3^2), (sqrt 3)]
The operator $ calls the function which is its left hand argument on the value which is its right hand argument. In the use of the example it "puts" the value 3 as additional argument of the sections in the list
Thus ($ 3) (4+) is (4+3). Analogously ($ 2) (4/) is (4/2)
The use of sections is easier to grasp using normal arithmetic operations. For instance: (/2) 4 is the same as 4/2 and thus 2

Dollar sign inside closed parens [duplicate]

This question already has answers here:
What does $ mean/do in Haskell?
(2 answers)
Closed 6 years ago.
Websocket snippet has a statement that has dollar sign inside closed parens like this,
any ($ fst client)
Since haskellers use $ sign instead of parens, why do we need parens here?
Why is there a $ symbol between parens?
I tried to see if $ is a function by doing
Prelude>:t $
But it threw the error, parse error on input $
In Haskell, operators are just normal functions that have names made up of symbols and used infix by default. You can use them just like a normal identifier by wrapping them in parentheses:
λ> :t (+)
(+) :: Num a => a -> a -> a
$ is just an operator like this itself. It represents function application and is defined as follows:
f $ x = f x
You can get its type just like (+):
λ> :t ($)
($) :: (a -> b) -> a -> b
Haskell operators can also be partially applied like normal functions, by wrapping them in parentheses with arguments to one side. For example, (+ 1) is the same as \ x -> x + 1 and (1 +) is the same as \x -> 1 + x.
This applies to $ too, so ($ fst client) is the same as \ f -> f $ fst client or just \ f -> f (fst client). The code snippet you have checks if any of a list of functions returns true given fst client.
($ fst client) is an operator section (just like (+ 1) or (* 2)) - it partially applies the operator to its right operand. A more verbose way to write it would be (\f -> f $ fst client).
So you're applying any to a function that takes another function and applies that function to the argument fst client.

How to define 'special' behavior for composite function in `.hs` file?

Composition is very normal in Haskell, but I just know that I can define special behavior of a composite function, says
Prelude> (floor . sqrt) (10^55)
3162277660168379365112938496
Prelude> let (floor . sqrt) n | n < 2 = n | otherwise = head $ dropWhile (\x -> x^2 > n) $ iterate (\x -> (x + n `div` x) `div` 2) (n `div` 2)
Prelude> (floor . sqrt) (10^55)
3162277660168379331998893544
The result from special define function is correct (because of floating point error in the first one).
Now I want to do the same inside .hs file, like
(floor . sqrt) n
| n < 2 = n
| otherwise = head $ dropWhile (\x -> x^2 > n)
$ iterate (\x -> (x + n `div` x) `div` 2) (n `div` 2)
main = do
print $ (floor . sqrt) (10^55)
This time ghc yelling at me
Ambiguous occurrence `.'
It could refer to either `Main..', defined at me.hs:1:8
or `Prelude..',
imported from `Prelude' at me.hs:1:1
(and originally defined in `GHC.Base')
So does it possible to define function like this in .hs file? (Define it inside main with let is okey, however).
First of all, your example in GHCi is not defining a special composition of floor and sqrt. Instead, it's defining an operator (.) which takes three arguments named floor, sqrt, and n and hides the existing standard function named (.).
You then apply your new function to the standard library functions floor and sqrt, which become the parameters with the same names in your new (.) function.
The error you get is because a top-level definition does not automatically hide the existing definition, and anyway that's clearly not what you actually want to do.
Now, you can certainly define an entirely new function (hopefully with its own name, as in groovy's answer) to do your specialized floor . sqrt function, but there's no way in Haskell itself to define it as a specialized version of the existing functions.
What you might be thinking of, and is possible, is using compiler pragma rewrite rules in GHC to automatically replace specific expressions with equivalent, improved versions. You should be careful that your rewritten form gives the same answer as what it replaces, though. Otherwise you're risking some really baffling debugging sessions.
How about this?
floorSqrt n
| n < 2 = n
| otherwise = head $ dropWhile (\x -> x^2 > n)
$ iterate (\x -> (x + n `div` x) `div` 2) (n `div` 2)
main = do
print $ floorSqrt (10^55)

Resources