![haskell list comprehension haskell list comprehension](https://sgp1.digitaloceanspaces.com/ffh-space-01/9to5answer/uploads/post/avatar/789854/template_how-to-obtain-a-subarray-in-python-320220714-3538670-iji9c0.jpg)
For the purpose of illustration, I'm not going to use the built-in list type, since it already is an instance of a monad and we would run into name conflicts.
![haskell list comprehension haskell list comprehension](https://miro.medium.com/max/1400/1*tvYnaEVr11Sdqf0vjEE61w.png)
Let's define the monadic type, List a, for non-deterministic computations. Handcrafted List MonadĪ monadic function returns a monadic type. In order to be able to compose them, we define a monad. Our chess program would probably have many such non-deterministic functions as well as some regular ones. In essence, we create a function that returns all possible results at once. The result of move is non-deterministic.Ī computation returning a non-deterministic result of type a is not a pure function, but it can be made into one by transforming its result type from a to a list of a. But what should move return? There are many possible moves in almost every situation. In order to make two moves, you would compose two such compuatations, etc. The basic routine in such a program would likely be called move: it would take a state of the chessboard and return a new state after a move has been made. Only one such move will materialize, but all of them have to be taken into account in planning the strategy. It has to anticipate the moves of a non-deterministic opponent. Think of a chess program that evaluates future moves. It's the kind of computation that, instead of producing a single result, might produce many. Let's illustrate this on a particular type of computation: the non-deterministic computation. Each monad provides a mechanism for composing such monadic functions.Īs we have seen, the do notation simplifies the syntax of composing multiple monadic functions. Functions that return a monadic type are called monadic functions. There is a surprisingly large class of such computations that can be turned into pure functions by just modifying their return types.Ī monad describes the way of transforming the return type of a particular kind of computation into a fancier monadic type. However, many traditional notions of computation are expressed in a pseudo-functional way: with procedures that take arguments and return results but also do some non-functional shenanigans. Pure functional programming reduces couplings to the very minimum - it's just plugging the output of one function to the input of another. There is overwhelming evidence that hidden couplings are a major source of bugs in both single-threaded and (even more so!) multi-threaded code. The quality of this decomposition is measured by how much coupling there is between the pieces, and how well we - and the compiler - can control and verify it. When complexity reaches a certain level, we start decomposing larger computations into smaller ones. The goal of programming is to write programs that perform computations.