Introducing the Haskell language

Tram Ho

Functional Programming

First, let’s consider two concepts:

• Imperative Programming: Programming commands, we use commands to change the state of the program. We will guide the program to step by step from beginning to end, or repeat certain commands, …

• Declarative Programming: Programming declarations, we will tell the program what we want, not how to do it. We do not specify the steps as in order programming.

Functional Programming is a branch in Declarative Programiming, in which, we will take the function as a basic unit (similar in object-oriented programming, the object will be the basic unit). In general, we have the following characteristics:

1. Purity

A function called pure if it takes parameters is a value and always returns a value without changing any external state. And with the same input, the function will return a corresponding value.

For example, consider a function in Swift as follows:

This function is pure because it doesn’t change anything outside. However, the following function is not pure because of the same input that returns different values:

But like that, printing a line of text to the screen also causes a change of state, so how do I use only pure functions? In Functional Programming, we must also have IO operations, which are impure operations, they will be encapsulated into one place to facilitate management. The function of Functional Programming is to minimize the side effects by accessing them, not completely removing them.

2. Immutability

There will be no change in a numerical variable in Functional Programming, a value stored in a variable will forever receive that value, generally it is a const variable . You have learned that Swift will definitely be used to a lot of let keywords, there are probably many reasons for this, we see that it minimizes errors when using const variable (and one of the main reasons is that swiftc will roar every time a variable just assigns once, we use var )

3. Recursion

In Functional Programming, we do not have keywords like for, while, repeat, forEach, ... To implement loops, we will use recursion. For example:

A function that finds the largest value in an integer array by recursion must be familiar to many people. Here int const* const indicates that arr must point to a fixed address and the values ​​it points to must be fixed to preserve immutability (the compiler will almost always change something) .

Perl programming language
Build multi-lingual database


Haskell is a pure functional programming language (Pure Functional Programming), is a compiled language, and is a static language, but don’t worry too much, the compiler will help us a lot in self-debugging. . Haskell is lazy (Lazy evaluation), unless forced to do it, Haskell will never execute calculations. A simple example has two repeat and take functions as follows:

If it is Python , we will write the following:

However, in Python , when we call take(3, repeat(7)) , the program will calculate repeat(7) before and after take later. However, when calculating repeat(7) , we will be immediately subjected to a maximum recursion depth exceeded because repeat(7) is an infinite list of 7 (We can edit the repeat function to make it a generator but here not the main purpose of the article). Now look at Haskell , if anyone doesn’t know, f x1 x2 ... is the implementation of a function f with the parameters x1, x2, ... and x:xs can be interpreted as x as the first element of a list and xs are interpreted as “high probability is the rest” (not the “rest”, only “high probability is the rest”). Now look at Haskell deploying the take 3 (repeat 7) :

With sample (x:xs) in the definition, it will convert repeat 7 to 7 : repeat 7 whenever called. Everything Haskell pure is lazy, but there is still a function that allows us to pre-calculate the parameter value before being executed (and of course it cannot be written entirely in Haskell ). Haskell ‘s laziness also causes some troubles:

This function takes a list and returns the sum of the elements of that list, with the lazyness of the language, it will do the following:

Having too many expressions not yet evaluated, Haskell now creates too much thunk . To limit this, as introduced above, there is a function that allows to evaluate a certain value first, Haskell gives us seq :

Where a will be evaluated, or simpler we just need to put ! before the variable we need to evaluate before the function runs with the -XBangPatterns command flag. So we will rewrite the above function as follows:


And let’s look at how this function works much better than before:

With && , it is also a function:

We perform the following two operations:

The following calculation will be slower because we force Haskell to calculate the value behind while not being needed.

What Haskell compiles and how long it takes to run is hard to predict, remembering the garbage collector so Haskell often not suitable for embedded systems, where memory management and security are needed. absolute latency. Also the source code of a binary binary file from Haskell is very large, so it is not suitable for embedded systems with limited memory. As well as writing an application with C++ frameworks like Qt , Haskell in application programming is also very painful. Haskell is best used when creating a compiler , concurenccy or parsing …

The syntax of the language is more mathematical than informatics, for example, to represent a set of even numbers in paragraphs 1 to 10 , mathematically, we will write left overline {1, 10} | 2 | x right } {x 1, 10 | 2 | x} or left {x | x inline {1, 10}; wedge 2 | x right } {x | x 1, 10 2 | x}. With the second way of writing, we will implement it with Haskell with a simple switch : to <- :

The results will return [2, 4, 6, 8, 10] . To list the set of 3 integers without negative numbers with a sum equal to 6, we will have:

I learned Haskell just because of this, regression, combinatorial, … formula models can be implemented by Haskell. For example, the problem of counting to see how much the n non-negative integers whose sum is m . Of course according to Euler candy division result will be Binom {n – 1} {m + n – 1} (m + n 1 n 1), but let’s pretend naive as to what it was working with Bayes’ theorem in Machine Learning, we will list all into a list and count the number of elements of that list:

We perform length $ tupleWithSum 3 6 , the results of 28 primary by Binom {3-1} {8 + 3-1} (8 + 3-1 3-1). Look at that function and design it with the mathematical model, it will be written S_ {n + 1, m} = left {(x, A); x overline {0, m}, A in S_ {n-1, m – x} right } S n + 1, m = {(x, A) | x 0, m, A S n 1, m x } .

Thanks to Haskell , I learned how to deploy something like quy hoạch động through đệ quy :

Overall, Haskell made me more interested than I thought, even though it was difficult, but it was worth studying for programming thinking.

How to choose a programming language is reasonable?

Top 10 programming languages ​​to study in 2019 – Guaranteed extremely high salaries
Share the news now

Source : viblo