Functional application in Haskell

Well, it was a long day, and my brain could not function at the Haskell level, but I just can not understand one example from "Learn You a Haskell".

The section is called Function Application with $, and there is an example of how $ can be defined:

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

So far, everything is clear. I understand all the examples in the section, except for the last:

 ghci> map ($ 3) [(4+), (10*), (^2), sqrt] [7.0,30.0,9.0,1.7320508075688772] 

Here we display ($ 3) through the list of functions and get the result of applying these functions to 3 . But how is this possible?

From the first code snippet it is clear that the first argument is a function, we can even write:

 *Main> ($) sqrt 4 2.0 

Now ($ 3) is a partial application of the $ function, but 3 continues to function! So 3 should be a function or what?

There is another riddle: what is this (4+) ? I know that (+4) is a partial application of function + , so (4+) should be a partial application of function 4 ? Nonsense. What trick works here?

+6
source share
3 answers

($ 3) and (+ 4) are not partial applications - these are operator sections. A partial application will look like (($) 3) or ((+) 4) .

The section of the form operator (? x) (where ? Denotes an arbitrary infix operator) binds the right operand of the operator, i.e. is it equivalent to \y -> y ? x \y -> y ? x . Similarly, the operator section (x ?) Binds the left operand and is thus equivalent to a partial application.

+12
source

I think you are confusing operator sections. This allows you to partially apply the operator with one of its arguments, so you can have the operators (+4) and (4+) , where 4 is the second and then the first argument + respectively. A more understandable example would be ("Hello" ++) versus (++ "world") , the former adds "Hello" to the beginning of the line, and the latter adds "world" to the end of the line.

This contrasts with the use of prefix operators that only have parsers. In this form, the following equivalents:

 > let join = (++) > join "Hello, " "world" "Hello, world" > (++) "Hello, " "world" "Hello, world" 

In prefix form, you treat the operator as a normal function and it takes its first and then second arguments in order. In operator sections, it is important which side of the operator the argument is on.


So, in your example, you have a partial application ($ 3) , you can reduce it as

 map ($ 3) [(4+), (10*), (^2), sqrt] [($ 3) (4+), ($ 3) (10 *), ($ 3) (^ 2), ($ 3) sqrt] [4 + 3, 10 * 3, 3 ^ 2, sqrt 3] [7.0, 30.0, 9.0, 1.7320508075688772] 
+6
source

You are confused with sections. A good way to understand the concept of sections is with an example:

 (<^>) :: Int -> Float -> Int a <^> b = a 

The above function is a useless function that returns the first parameter regardless of the second parameter. But it accepts Int and then Float as input.

Now, because of the sections, you can apply any of your arguments:

 λ> let a = (3 <^>) λ> :ta a :: Float -> Int λ> let b = (<^> 3.0) λ> :tb b :: Int -> Int 

See how types a and b different from sections.

+4
source

Source: https://habr.com/ru/post/974982/


All Articles