Higher-Order Function & Currying Function

Tram Ho

Let’s not rush into the new concepts that we have planned in this article. In the opening section here we will talk about some elements related to the concepts in the previous lesson. First we’ll talk about variables created in binding syntaxes like let .. in .

Although Functional languages ​​are all designed with strict data-typing characteristics. However, the generated variables will all have implicit data types and the compiler will automatically find information from the value assigned to each variable. And then to ensure consistency and rigor in the code logic, the Variables in the default Functional Programming -specific design environment are left unchanged.

This means that Variables in Functional environments like Elm , Haskell , PureScript , are functionally equivalent to constant in other programming environments. Even in the operation of defining functions, the elements to the left of the = symbol, including the function naming variable and input parameters, are immutable elements. The concept of immutable and side-effect is used a lot in the Functional environment and we will note it from here.

Higher-Order Function

Higher-Order Functions are roughly understood as Functions with a higher observation position.

For example, when we pass a Function g into the call of Function f and then the logic operating inside Function f will make the call of Function g to delegate some work. Now Function f is considered as Higher-Order Function compared to Function g ; Because f already knows information about g through parameter types, and g knows nothing about f .

In the above example, we passed the not function into the map module List , and delegated the inverse of the Bool values ​​inside the passed List in the next parameter position. Thus List.map at least knows that the function passed in the first argument of the form (a -> b) converts the value of an element in the List . And the operation logic of List.map is to call the not function with each element of List in turn to obtain new values ​​and create a completely new List of results.

We can also use lambda Anonymous Function expressions that are syntactically similar to JavaScript to pass to List.map . In this case, Elm will implicitly assume the data type of the input parameter to the Anonymous Function is the type of the data in the List , and the returned result will depend on the logic inside the lambda .

And this is how JavaScript has built-in HOD support for coders to use with the map method of Array arrays.

The concept of Higher-Order Function can also be expressed in another case, when Function f returns a value of a Function g . At this time, f is also considered as a function with a higher observation angle than g . However, for a descriptive example, we will move on to the next related concept, Currying Function .

Currying Function

In Elm ‘s REPL window, let’s try to check the type information of List.map , because we already know the Higher-Order Function and maybe there will be times when we want to define such a HOD function ourselves.

So we have List.map which is a function <function> , which takes the first parameter a function (a -> b) , and the second parameter a list List a , and returns the result. is a new List b . However, we can also read the type information of List.map with the following parameter and the results are grouped by parentheses () like this:

That means List.map is a function <function> , which takes a function (a -> b) as a parameter and returns a new function (List a -> List b) . So we can understand List.map is also the Higher-Order Function of the function (List a -> List b) .

Now from the perspective of using the List.map function, we will be able to create a new function (List a -> List b) and then use this function for different List .

Thus List.map was used by applying partial application parameters, instead of parameters being passed in at the same time in a function call. And manipulating the function definition with such layered parameters so that we can then partially apply it is called Currying Function .

In many functional programming languages ​​including Elm and Haskell , and the PureScript , the function definition syntax automates Currying . In other languages, if the syntax is not supported, we will have to write a bit more verbose, for example, JavaScript before the lambda syntax. As for languages ​​that support lambda syntax, we only need to lambda single-parameter lambdas.

However, if we were to define an Array.map function like this ourselves in JavaScript , we would obviously need to use Imperative elements like creating an empty result array and updating it through loops. The important point that we need to note is that the original $array should not be changed in content after any operation.

Share the news now

Source : Viblo