# Functional thinking. Part 6

3r33630. We continue our series of articles on functional F # programming. Today we will talk about the associativity and composition of functions, as well as compare the composition and the pipeline. Look under the cat!
3r33535.  3r33655. 3r33630. 3r33535.  3r33655. 3r3599.  3r33655. 3r3618.
The first part is 3r3647.
3r33655. 3r3618.
The second part is 3r3647.
3r33655. 3r3618.
Third part 3r3647.
3r33655. 3r3618.
3r3338. Fourth part 3r3647.
3r33655. 3r3618.
The fifth part is 3r3647.

3r33655.
3r33535.  3r33655. 3r33548. Associativity and composition of functions 3r33549. 3r33535.  3r33655.

#### Associativity of functions

3r33535.  3r33655. 3r33630. Suppose there is a chain of functions written in a row. In what order will they be combined?
3r33535.  3r33655. 3r33630. For example, what does this feature mean?
3r33535.  3r33655. 3r33535. 3r33535. let F x y z = x y z 3r33535. 3r33535.  3r33655. 3r33630. Does this mean that function ` y ` should be applied to the argument ` z ` and then the result should be passed to ` x ` ? Ie: 3r3648. 3r33535.  3r33655. 3r33535. 3r33535. let F x y z = x (y z) 3r33535. 3r33535.  3r33655. 3r33630. Or function 3r3602. x applies to the argument 3r3602. y after which the function obtained as a result will be calculated with the argument ` z ` ? Ie: 3r3648. 3r33535.  3r33655. 3r33535. 3r33535. let F x y z = (x y) z 3r33535. 3r33535.  3r33655.
1.  3r33655. 3r3618. True to the second option.  3r33655. 3r3618. The use of functions has 3r33645. left associativity 3r3r6646. .  3r33655. 3r3618. 3r3602. x y z It means the same as 3r3602. (x y) z .  3r33655. 3r3618. A
` w x y z ` equals ` ((w x) y) z ` .  3r33655. 3r3618. This should not look amazing.  3r33655. 3r3618. We have already seen how partial application works.  3r33655. 3r3618. If you talk about 3r3r2602. x as a function with two parameters, then ` (x y) z ` - This is the result of the partial application of the first parameter, followed by the argument 3r3602. z to intermediate function.  3r33655. 3r3148. 3r33535.  3r33655. 3r33630. If you need the right associativity, you can use brackets or pipe. The following three entries are equivalent: 3r33535.  3r33655. 3r33535. 3r33535. let F x y z = x (y z) 3r33655. let F x y z = y z |> x //use the
direct pipeline. let F x y z = x <| y z
//использование обратного конвейера 3r33535. 3r33535.  3r33655. 3r33630. As an exercise, try to display the signatures of these functions without real computation. 3r33535.  3r33655.

#### Composition of functions

3r33535.  3r33655. 3r33630. We have mentioned the composition of functions several times, but what does this term really mean? It seems daunting at first glance, but in reality everything is quite simple. 3r33535.  3r33655. 3r33630. Let's say we have a function "f" that matches the type "T1" to the type "T2". We also have a function "g" that converts the type "T2" to the type "T3". Then we can connect the output "f" and the input "g" by creating a new function that converts the type "T1" to the type "T3". 3r33535.  3r33655. 3r33630. 3r33180. 3r33535.  3r33655. 3r33630. For example: 3r3648. 3r33535.  3r33655. 3r33535. 3r33535. let f (x: int) = float x * 3.0 //f is a function of type int-> float
let g (x: float) = x> 4.0 //g is a function of type float-> bool 3r33535. 3r33535.  3r33655. 3r33630. We can create a new function "h", which takes the output "f" and uses it as input for "g". 3r33535.  3r33655. 3r33535. 3r33535. let h (x: int) =
let y = f (x)
g (y) //return the result of calling g 3r33535. 3r33535.  3r33655. 3r33630. Slightly more compact: 3r33535.  3r33655. 3r33535. 3r33535. let h (x: int) = g (f (x)) //h is a function of type int-> bool
3r33655. //test 3r33655. h 1
h 2 3r33535. 3r33535.  3r33655. 3r33630. 3r3645. So far, so simple. This is interesting, we can define a new function "compose", which takes the functions "f" and "g" and combines them without even knowing their signatures. 3r33535.  3r33655. 3r33535. 3r33535. let compose f g x = g (f (x)) 3r33535. 3r33535.  3r33655. 3r33630. After execution, you can see that the compiler correctly decided that " ` F ` " Is a function of a generalized type, ` 'a ` to generalized type 3r3602. 'b , and " ` g ` " is limited to input of type 3r3602. 'b : 3r33535.  3r33655. 3r33535. 3r33535. val compose: ('a ->' b) -> ('b ->' c) -> 'a ->' c 3r33535. 3r33535.  3r33655. 3r33630. (Note that generalized composition of operations is possible only because each function has exactly one input parameter and one conclusion. This approach is impossible in non-functional languages.) 3r3648. 3r33535.  3r33655. 3r33630. As we see, this definition is used for the operator "3r3602. ". 3r33535.  3r33655. 3r33535. 3r33535. let () f g x = g (f (x)) 3r33535. 3r33535.  3r33655. 3r33630. Thanks to this definition, it is possible to build new functions based on existing ones with the help of composition. 3r33535.  3r33655. 3r33535. 3r33535. let add1 x = x + 1
let times2 x = x * 2
3r33655. //test 3r33655. add1Times???r3r3603. 3r33535. 3r33535.  3r33655. 3r33630. Explicit recording is quite cumbersome. But you can make its use easier to understand. 3r33535.  3r33655. 3r33630. First, you can get rid of parameter 3r3602. x , and the composition will return partial application. 3r33535.  3r33655. 3r33535. 3r33535. let add1Times2 = () add1 times2 3r33535. 3r33535.  3r33655. 3r33630. Secondly, because 3r3602. is a binary operator, you can put it in the center. 3r33535.  3r33655. 3r33535. 3r33535. let add1Times2 = add1 times2 3r33535. 3r33535.  3r33655. 3r33630. The use of the composition makes the code cleaner and clearer. 3r33535.  3r33655. 3r33535. 3r33535. let add1 x = x + 1
let times2 x = x * 2
3r33655. //as of the old 3r33655. let add1Times2 x = times2 (add1 x)
3r33655. //new

## About the authors of the translation

3r33535.  3r33655. 3r33630. Author translation 3r3631. 3r3645. @kleidemos
3r33535.  3r33655. Translation and editorial edits made by the Russian-speaking community for F # developers . We also thank r3r3640. 3r3645. @schvepsss
and 3r3644. 3r3645. @shwars