In Learn you a Haskell, it is given the following example:
map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
However, I don't understand why this works.
The signatures of the functions are
Prelude> :info ($)
($) :: (a -> b) -> a -> b
Prelude> :t ($ 3)
($ 3) :: Num a => (a -> b) -> b
However, -> is a left-associative operator, so $ :: (a -> b) -> a -> b is actually ((($ :: (a-b))-> a)-> b), so shouldn't 3 in ($ 3) correspond to (a->b) function that is the first "variable" of the function $? i.e why is ($ 3) a function of signature (a -> b) -> b
No,
->is a right-associative operator. In the Learn You a Haskell documentation, it says:A more verbose version of the type signatures of
($)and($ 3)are:we can write the type constructors in a more canonical form as:
This thus means that
$takes a function with signaturea -> b, and thus returns a function with signaturea -> b, it thus basically acts asid, except that it constrants the input to a function (and not just any type), and that you can use$easily whereas(`id` 3)is not that elegant.If we thus apply
3to thef $ 3operator, we know thatfwill have signaturef :: a -> b, and3will have typeNum a => a. If we work with operator sectioning with($ 3), we pass3as the "second" parameter (in Haskell every function has exactly one parameter, but here we assign it thus to the parameter that is the result of($) f, this thus means that the type of($ 3)isNum a => (a -> b) -> b.