2

This haskell piece of code

map ($ 3) [(4+), (10*), (^2), sqrt]  

gives the output

[7.0,30.0,9.0,1.7320508075688772]  

I know that $ has the lowest precedence and hence the expression to the right of $ is evaluated together. But what I don't understand is how does ($ 3) behave as a function (Because Map takes a function and a list as parameters). I don't understand why each function in the list is applied to 3.

2 Answers 2

5

Remember that ($) is actually a function:

($) :: (a -> b) -> a -> b
f $ x = f x

($ 3) is shorthand for \f -> (f $ 3). And its type? Well:

3     ::                  Double -- for sake of simplicity
($)   :: (a      -> b) -> a      -> b
($ 3) :: (Double -> b)           -> b

So ($ 3) is a function that takes a function from Double to something and applies that function to 3. Now, if we use map, we end up with:

map ($ 3) [(4+), (10*), (^2), sqrt]  
 = [($ 3) (4+), ($ 3) (10*), ($ 3)(^2), ($ 3) sqrt]  
 = [(4+) $ 3, (10*) $ 3, (^2) $ 3, sqrt $ 3]  
 = [4 + 3, 10 * 3, 3 ^ 2, sqrt 3]
 = [7, 30, 9, sqrt 3]
Sign up to request clarification or add additional context in comments.

4 Comments

If dollar is a function shouldn't the function part be applied be applied to parameters instead of the applying the function to a paramter. I am pretty sure that I have got something wrong :) Just not able to figure what I have got wrong
@Ashwin err, what? What do you mean by "shouldn't the function part be applied be applied to parameters instead of the applying the function to a paramter"?
I mean shouldn't it be other way around. (4+) should take 3 as parameter instead of 3 taking (4+) as parameter?
No. ($3) takes (4+) as "parameter". Remember ($3) is a shorthand for ($3) = \f -> f $ 3, so ($3) (4+) is (4+) 3 or 4 + 3
3

Let's first review the type signature of ($):

ghci>> :t ($)
($) :: (a -> b) -> a -> b

And definition:

($) f x = f x

Or:

f $ x = f x

And above, we have a section where we've created a partially applied version of ($) with the second argument (of type a) set as 3. Now, we know that 3 has type Num a => a, so the type signature of our partial application must be Num a => (a -> b) -> b.

Next, let's look at each of the functions in our list, each of which will be an argument to ($ 3). As expected, they are functions and it turns out that their type Num a -> a -> a is actually more constrained than was required (so we're good). Just to be clear, we can look at what one application would entail:

($3) (4+)

Which we can rewrite without the section as:

($) (4+) 3

At which point it's pretty clear from the function definition above how application proceeds.

The last confusing part might be about the type of the list ($3) (4+) evaluates as 7, rather than 7.0 in the repl. If we recall that lists are homogeneous and notice that one of the functions in the list, sqrt, accepts and returns a floating value, we see that this type enforced for all applications.

2 Comments

How did you rewrite ($3) (4+) as ($) (4+) 3 ?
@Ashwin: ($3) = \f -> f $ 3, or \f -> ($) f 3 in prefix notation. Replace f by (4+).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.