Typos 3
This commit is contained in:
parent
b395818974
commit
0fb10448a0
33 changed files with 882 additions and 854 deletions
|
@ -2094,18 +2094,19 @@ main = do
|
||||||
|
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
Congratulation to get so far!
|
Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.
|
Now, some of the really hardcore stuff can start.
|
||||||
|
|
||||||
If you are like me, you should get the functional style.
|
If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don't really understand were to start to make a real program.
|
But you also don't really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:
|
And in particular:
|
||||||
|
|
||||||
- How do you deal with effects?
|
- How do you deal with effects?
|
||||||
- Why is there a strange imperative-like notation for dealing with IO?
|
- Why is there a strange imperative-like notation for dealing with IO?
|
||||||
|
|
||||||
Be prepared, answer might be difficult to get.
|
Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.
|
But they all be very rewarding.
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a>
|
||||||
|
@ -2116,7 +2117,7 @@ But they all be very rewarding.
|
||||||
|
|
||||||
> <%=tldr%>
|
> <%=tldr%>
|
||||||
>
|
>
|
||||||
> A typical function doing `IO` look a lot like an imperative language:
|
> A typical function doing `IO` looks a lot like an imperative program:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> f :: IO a
|
> f :: IO a
|
||||||
|
@ -2135,15 +2136,15 @@ But they all be very rewarding.
|
||||||
> - `action3 :: IO c`
|
> - `action3 :: IO c`
|
||||||
> - `action4 x y :: IO a`
|
> - `action4 x y :: IO a`
|
||||||
> - `x :: b`, `y :: c`
|
> - `x :: b`, `y :: c`
|
||||||
> - Few objects have the type `IO a`, this should help you to choose.
|
> - Few objects have the type `IO a`, this should help you choose.
|
||||||
> In particular you cannot use pure function directly here.
|
> In particular you cannot use pure functions directly here.
|
||||||
> To use pure function you could do `action2 (purefunction x)` for example.
|
> To use pure functions you could do `action2 (purefunction x)` for example.
|
||||||
|
|
||||||
In this section, I will explain how to use IO, not how they work.
|
In this section, I will explain how to use IO, not how it works.
|
||||||
You'll see how Haskell separate pure from impure part of the program.
|
You'll see how Haskell separates the pure from the impure parts of the program.
|
||||||
|
|
||||||
Don't stop because you're trying to understand the details of the syntax.
|
Don't stop because you're trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.
|
Answers will come in the next section.
|
||||||
|
|
||||||
What to achieve?
|
What to achieve?
|
||||||
|
|
||||||
|
@ -2170,7 +2171,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Or more interestingly, we remark each expression in the `do` block has a type of `IO a`.
|
Or more interestingly, we note that each expression in the `do` block has a type of `IO a`.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -2179,7 +2180,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
We should also remark the effect of the `<-` symbol.
|
We should also pay attention to the effect of the `<-` symbol.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
do
|
do
|
||||||
|
@ -2188,8 +2189,8 @@ do
|
||||||
|
|
||||||
If `something :: IO a` then `x :: a`.
|
If `something :: IO a` then `x :: a`.
|
||||||
|
|
||||||
Another important remark to use `IO`.
|
Another important note about using `IO`.
|
||||||
All line in a do block must have one of the two forms:
|
All lines in a do block must be of one of the two forms:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
action1 :: IO a
|
action1 :: IO a
|
||||||
|
@ -2204,14 +2205,14 @@ value <- action2 -- where
|
||||||
-- value :: b
|
-- value :: b
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
These two kind of line will correspond to two different way of sequencing actions.
|
These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.
|
The meaning of this sentence should be clearer by the end of the next section.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a>
|
||||||
|
|
||||||
Now let's see how this behave.
|
Now let's see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let's try:
|
Let's try:
|
||||||
|
|
||||||
|
@ -2225,7 +2226,7 @@ Let's try:
|
||||||
Argh! An evil error message and a crash!
|
Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.
|
The first evolution will be to answer with a more friendly message.
|
||||||
|
|
||||||
For this, we must detect, something went wrong.
|
In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type `Maybe`.
|
Use the type `Maybe`.
|
||||||
It is a very common type in Haskell.
|
It is a very common type in Haskell.
|
||||||
|
@ -2235,7 +2236,7 @@ It is a very common type in Haskell.
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
What is this thing? Maybe is a type which takes one parameter.
|
What is this thing? `Maybe` is a type which takes one parameter.
|
||||||
Its definition is:
|
Its definition is:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -2285,32 +2286,33 @@ main = do
|
||||||
Nothing -> error "Bad format. Good Bye."
|
Nothing -> error "Bad format. Good Bye."
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
In case of error, we prompt a nice error message.
|
In case of error, we display a nice error message.
|
||||||
|
|
||||||
Remark the type of each expression in the main's do block remains of the form `IO a`.
|
Note that the type of each expression in the main's do block remains of the form `IO a`.
|
||||||
The only strange construction is `error`.
|
The only strange construction is `error`.
|
||||||
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
||||||
|
|
||||||
One very important thing to note is the type of all the defined function.
|
One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains `IO` in its type: `main`.
|
There is only one function which contains `IO` in its type: `main`.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use `getListFromString` which is pure.
|
But main uses `getListFromString` which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.
|
||||||
|
|
||||||
Why purity matters?
|
Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:
|
I certainly forget many advantages, but the three main reasons are:
|
||||||
|
|
||||||
- It is far easier to think about pure code than impure one.
|
- It is far easier to think about pure code than impure one.
|
||||||
- Purity protect you from all hard to reproduce bugs due to border effects.
|
- Purity protects you from all the hard to reproduce bugs due to side effects.
|
||||||
- You can evaluate pure functions in any order or in parallel without risk.
|
- You can evaluate pure functions in any order or in parallel without risk.
|
||||||
|
|
||||||
This is why, you should generally put as most code as possible in pure functions.
|
This is why you should generally put as most code as possible inside pure functions.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a>
|
||||||
|
|
||||||
Our next evolution will be to ask the user again and again until it enters a valid answer.
|
Our next evolution will be to prompt the user again and again until she enters a valid answer.
|
||||||
|
|
||||||
We keep the first part:
|
We keep the first part:
|
||||||
|
|
||||||
|
@ -2326,7 +2328,7 @@ getListFromString :: String -> Maybe [Integer]
|
||||||
getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
Now, we create a function which will ask the user for an integer list
|
Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.
|
until the input is right.
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -2342,14 +2344,14 @@ askUser = do
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
This function is of type `IO [Integer]`.
|
This function is of type `IO [Integer]`.
|
||||||
Such a type means, that we retrieved a value of type `[Integer]` through some IO actions.
|
Such a type means that we retrieved a value of type `[Integer]` through some IO actions.
|
||||||
Some people might explain while waving their hands:
|
Some people might explain while waving their hands:
|
||||||
|
|
||||||
> «This is an `[Integer]` inside an `IO`»
|
> «This is an `[Integer]` inside an `IO`»
|
||||||
|
|
||||||
If you want to understand the details behind all of this, you'll have to read the next section.
|
If you want to understand the details behind all of this, you'll have to read the next section.
|
||||||
But sincerely, if you just want to _use_ IO.
|
But sincerely, if you just want to _use_ IO.
|
||||||
Just exercise a little and remember to think about the type.
|
Just practice a little and remember to think about the type.
|
||||||
|
|
||||||
Finally our main function is quite simpler:
|
Finally our main function is quite simpler:
|
||||||
|
|
||||||
|
@ -2362,21 +2364,21 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
We have finished with our introduction to `IO`.
|
We have finished with our introduction to `IO`.
|
||||||
This was quite a fast. Here are the main things to remind:
|
This was quite fast. Here are the main things to remember:
|
||||||
|
|
||||||
- in the `do` bloc, each expression must have the type `IO a`.
|
- in the `do` bloc, each expression must have the type `IO a`.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, `getLine`, `print`, `putStrLn`, etc...
|
For example, `getLine`, `print`, `putStrLn`, etc...
|
||||||
- Try to externalize the pure function as much as possible.
|
- Try to externalize the pure functions as much as possible.
|
||||||
- the `IO a` type means: an IO _action_ which return an element of type `a`.
|
- the `IO a` type means: an IO _action_ which returns an element of type `a`.
|
||||||
`IO` represent action; under the hood, `IO a` is the type of a function.
|
`IO` represents actions; under the hood, `IO a` is the type of a function.
|
||||||
Read the next section if you are curious.
|
Read the next section if you are curious.
|
||||||
|
|
||||||
If you exercise a bit, you should be able to _use_ `IO`.
|
If you practice a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> _Exercises_:
|
> _Exercises_:
|
||||||
>
|
>
|
||||||
> - Make a program that sum all its argument. Hint: use the function `getArgs`.
|
> - Make a program that sums all of its arguments. Hint: use the function `getArgs`.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
|
@ -2386,15 +2388,15 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> Here is a <%=tldr%> for this section.
|
> Here is a <%=tldr%> for this section.
|
||||||
>
|
>
|
||||||
> To separate pure from impure part,
|
> To separate pure and impure parts,
|
||||||
> the main is defined as a function
|
> `main` is defined as a function
|
||||||
> which modify the state of the world
|
> which modifies the state of the world
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main :: World -> World
|
> main :: World -> World
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> A function is granted to have side effect only if it gets this value.
|
> A function is guaranteed to have side effects only if it has this type.
|
||||||
> But look at a typical main function:
|
> But look at a typical main function:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -2406,17 +2408,17 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
||||||
> which must be passed to the next action.
|
> which must be passed on to the next action.
|
||||||
>
|
>
|
||||||
> We create a function `bind` or `(>>=)`.
|
> We create a function `bind` or `(>>=)`.
|
||||||
> With `bind` we need no more temporary name.
|
> With `bind` we don't need temporary names anymore.
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main =
|
> main =
|
||||||
> action1 >>= action2 >>= action3 >>= action4
|
> action1 >>= action2 >>= action3 >>= action4
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> Bonus: Haskell has a syntactical sugar for us:
|
> Bonus: Haskell has syntactical sugar for us:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main = do
|
> main = do
|
||||||
|
@ -2426,11 +2428,11 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
> action4 v3
|
> action4 v3
|
||||||
> ~~~
|
> ~~~
|
||||||
|
|
||||||
Why did we used some strange syntax, and what exactly is this `IO` type.
|
Why did we use this strange syntax, and what exactly is this `IO` type?
|
||||||
It looks a bit like magic.
|
It looks a bit like magic.
|
||||||
|
|
||||||
For now let's just forget about all the pure part of our program, and focus
|
For now let's just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:
|
on the impure parts:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: IO [Integer]
|
askUser :: IO [Integer]
|
||||||
|
@ -2449,33 +2451,33 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First remark; it looks like an imperative structure.
|
First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a `while` in Haskell.
|
For example, if you wish you could create a `while` in Haskell.
|
||||||
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
||||||
|
|
||||||
But, you should had remarked the notation is a bit unusual.
|
But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.
|
Here is why, in detail.
|
||||||
|
|
||||||
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.
|
The fact that a file exists or not can be seen as different states of the world.
|
||||||
|
|
||||||
For Haskell this state is not hidden.
|
For Haskell this state is not hidden.
|
||||||
It is explicitly said `main` is a function that _potentially_ change the state of the world.
|
It is explicitly said `main` is a function that _potentially_ changes the state of the world.
|
||||||
It's type is then something like:
|
Its type is then something like:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
main :: World -> World
|
main :: World -> World
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not all function could have access to this variable.
|
Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn't provided to should be pure[^032001].
|
Functions to which the world variable isn't provided are pure[^032001].
|
||||||
|
|
||||||
[^032001]: There are some _unsafe_ exception to this rule. But you shouldn't see such usage on a real application except might be for some debugging purpose.
|
[^032001]: There are some _unsafe_ exceptions to this rule. But you shouldn't see such use on a real application except maybe for debugging purpose.
|
||||||
|
|
||||||
Haskell consider the state of the world is an input variable for `main`.
|
Haskell considers the state of the world as an input variable to `main`.
|
||||||
But the real type of main is closer to this one[^032002]:
|
But the real type of main is closer to this one[^032002]:
|
||||||
|
|
||||||
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
||||||
|
@ -2496,17 +2498,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First, we remark, that all function which have side effect must have the type:
|
First, we note that all functions which have side effects must have the type:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
World -> (a,World)
|
World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Where `a` is the type of result.
|
Where `a` is the type of the result.
|
||||||
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
||||||
|
|
||||||
Another thing to remark is the trick to fix the order of evaluation.
|
Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate `f a b`, you generally have many choices:
|
In Haskell, in order to evaluate `f a b`, you have many choices:
|
||||||
|
|
||||||
- first eval `a` then `b` then `f a b`
|
- first eval `a` then `b` then `f a b`
|
||||||
- first eval `b` then `a` then `f a b`.
|
- first eval `b` then `a` then `f a b`.
|
||||||
|
@ -2527,7 +2529,7 @@ Under the hood, `print` will evaluate as:
|
||||||
- evaluate as `((),new world id)`.
|
- evaluate as `((),new world id)`.
|
||||||
|
|
||||||
Now, if you look at the style of the main function, it is clearly awkward.
|
Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let's try to make the same to the askUser function:
|
Let's try to do the same to the askUser function:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: World -> ([Integer],World)
|
askUser :: World -> ([Integer],World)
|
||||||
|
@ -2562,9 +2564,9 @@ askUser w0 =
|
||||||
This is similar, but awkward.
|
This is similar, but awkward.
|
||||||
Look at all these temporary `w?` names.
|
Look at all these temporary `w?` names.
|
||||||
|
|
||||||
The lesson, is, naive IO implementation in Pure functional language is awkward!
|
The lesson, is, naive IO implementation in Pure functional languages is awkward!
|
||||||
|
|
||||||
Fortunately, some have found a better way to handle this problem.
|
Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:
|
Each line is of the form:
|
||||||
|
|
||||||
|
@ -2580,8 +2582,7 @@ Each function `f` must have a type similar to:
|
||||||
f :: World -> (a,World)
|
f :: World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not only this, but we can also remark we use them always
|
Not only this, but we can also note that we always follow the same usage pattern:
|
||||||
with the following general pattern:
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (y,w1) = action1 w0 in
|
let (y,w1) = action1 w0 in
|
||||||
|
@ -2590,7 +2591,7 @@ let (t,w3) = action3 w2 in
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Each action can take 0 to some parameters.
|
Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.
|
And in particular, each action can take a parameter from the result of a line above.
|
||||||
|
|
||||||
For example, we could also have:
|
For example, we could also have:
|
||||||
|
@ -2604,7 +2605,7 @@ let (_,w3) = action3 x z w2 in
|
||||||
|
|
||||||
And of course `actionN w :: (World) -> (a,World)`.
|
And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
> IMPORTANT, there are only two important pattern for us:
|
> IMPORTANT, there are only two important patterns to consider:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> let (x,w1) = action1 w0 in
|
> let (x,w1) = action1 w0 in
|
||||||
|
@ -2620,7 +2621,7 @@ And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
||||||
|
|
||||||
Now, we will make a magic trick.
|
Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol "disappear".
|
We will make the temporary world symbol "disappear".
|
||||||
We will `bind` the two lines.
|
We will `bind` the two lines.
|
||||||
Let's define the `bind` function.
|
Let's define the `bind` function.
|
||||||
|
@ -2646,18 +2647,18 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
`getLine` is an IO action which take a world as parameter and return a couple `(String,World)`.
|
`getLine` is an IO action which takes a world as parameter and returns a couple `(String,World)`.
|
||||||
Which can be said as: `getLine` is of type `IO String`.
|
Which can be summarized as: `getLine` is of type `IO String`.
|
||||||
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
||||||
|
|
||||||
The function `print` is also interresting.
|
The function `print` is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type `((),World)`.
|
It then returns a couple of type `((),World)`.
|
||||||
This means it changes the world state, but don't give anymore data.
|
This means it changes the state of the world, but doesn't yield anymore data.
|
||||||
|
|
||||||
This type help us simplify the type of `bind`:
|
This type helps us simplify the type of `bind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
bind :: IO a
|
bind :: IO a
|
||||||
|
@ -2683,7 +2684,7 @@ action2 :: a -> IO b
|
||||||
(y,w2) :: IO b
|
(y,w2) :: IO b
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Doesn't seem familiar?
|
Doesn't it seem familiar?
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -2693,7 +2694,7 @@ Doesn't seem familiar?
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
The idea is to hide the World argument with this function. Let's go:
|
The idea is to hide the World argument with this function. Let's go:
|
||||||
As example imagine if we wanted to simulate:
|
As an example imagine if we wanted to simulate:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -2708,7 +2709,7 @@ Now, using the bind function:
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
As print is of type (World -> ((),World)), we know res = () (null type).
|
As print is of type (World -> ((),World)), we know res = () (null type).
|
||||||
If you didn't saw what was magic here, let's try with three lines this time.
|
If you didn't see what was magic here, let's try with three lines this time.
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -2725,8 +2726,8 @@ Which is equivalent to:
|
||||||
print (line1 ++ line2)))
|
print (line1 ++ line2)))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Didn't you remark something?
|
Didn't you notice something?
|
||||||
Yes, there isn't anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is _MA_. _GIC_.
|
This is _MA_. _GIC_.
|
||||||
|
|
||||||
We can use a better notation.
|
We can use a better notation.
|
||||||
|
@ -2741,7 +2742,7 @@ Let's use `(>>=)` instead of `bind`.
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Ho Ho Ho! Happy Christmas Everyone!
|
Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:
|
Haskell has made syntactical sugar for us:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
do
|
do
|
||||||
|
@ -2762,8 +2763,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
||||||
|
|
||||||
But what for line not using the `<-`?
|
But what about the lines not using the `<-`?
|
||||||
Easy another function `blindBind`:
|
Easy, another function `blindBind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
blindBind :: IO a -> IO b -> IO b
|
blindBind :: IO a -> IO b -> IO b
|
||||||
|
@ -2771,7 +2772,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
I didn't simplified this definition for clarity purpose.
|
I didn't simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we'll use the `(>>)` operator.
|
Of course we can use a better notation, we'll use the `(>>)` operator.
|
||||||
|
|
||||||
And
|
And
|
||||||
|
@ -2798,7 +2799,7 @@ putInIO :: a -> IO a
|
||||||
putInIO x = IO (\w -> (x,w))
|
putInIO x = IO (\w -> (x,w))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
This is the general way to put pure value inside the "IO context".
|
This is the general way to put pure values inside the "IO context".
|
||||||
The general name for `putInIO` is `return`.
|
The general name for `putInIO` is `return`.
|
||||||
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
||||||
|
|
||||||
|
@ -2849,7 +2850,7 @@ main = askUser >>=
|
||||||
\list -> print $ sum list
|
\list -> print $ sum list
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
You can compile this code to verify it continues to work.
|
You can compile this code to verify it keeps working.
|
||||||
|
|
||||||
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
||||||
|
@ -2859,11 +2860,11 @@ Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<%= blogimage("dali_reve.jpg","Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
<%= blogimage("dali_reve.jpg","Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
||||||
|
|
||||||
Now the secret can be revealed: `IO` is a _monad_.
|
Now the secret can be revealed: `IO` is a _monad_.
|
||||||
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.
|
But mainly, you have access to a coding pattern which will ease the flow of your code.
|
||||||
|
|
||||||
> **Important remarks**:
|
> **Important remarks**:
|
||||||
>
|
>
|
||||||
|
@ -2894,13 +2895,13 @@ class Monad m where
|
||||||
>
|
>
|
||||||
> - the keyword `class` is not your friend.
|
> - the keyword `class` is not your friend.
|
||||||
> A Haskell class is _not_ a class like in object model.
|
> A Haskell class is _not_ a class like in object model.
|
||||||
> A Haskell class has a lot similarities with Java interfaces.
|
> A Haskell class has a lot of similarities with Java interfaces.
|
||||||
> A better word should have been `typeclass`.
|
> A better word should have been `typeclass`.
|
||||||
> That means a set of types.
|
> That means a set of types.
|
||||||
> For a type to belong to a class, all function of the class must be provided for this type.
|
> For a type to belong to a class, all functions of the class must be provided for this type.
|
||||||
> - In this particular example of type class, the type `m` must be a type that take an argument.
|
> - In this particular example of type class, the type `m` must be a type that takes an argument.
|
||||||
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
||||||
> - To be a useful monad, your function must obey some rule.
|
> - To be a useful monad, your function must obey some rules.
|
||||||
> If your construction does not obey these rules strange things might happens:
|
> If your construction does not obey these rules strange things might happens:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -2911,13 +2912,13 @@ class Monad m where
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
There exists a lot of different type that are instance of `Monad`.
|
There are a lot of different types that are instance of `Monad`.
|
||||||
One of the easiest to describe is `Maybe`.
|
One of the easiest to describe is `Maybe`.
|
||||||
If you have a sequence of `Maybe` values, you could use monad to manipulate them.
|
If you have a sequence of `Maybe` values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep `if..then..else..` constructions.
|
It is particularly useful to remove very deep `if..then..else..` constructions.
|
||||||
|
|
||||||
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.
|
if you can afford to follow a list of operations without being negative.
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -2957,7 +2958,7 @@ main = do
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a>
|
<hr/><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a>
|
||||||
|
|
||||||
Now, let's make it better using Maybe and the fact it is a Monad
|
Now, let's make it better using Maybe and the fact that it is a Monad
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3013,7 +3014,7 @@ main = do
|
||||||
print $ eligible 299 -- Nothing
|
print $ eligible 299 -- Nothing
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
We have proved Monad are nice to make our code more elegant.
|
We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for `Maybe` can be used
|
Note this idea of code organization, in particular for `Maybe` can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.
|
In fact, this is the kind of construction we make naturally.
|
||||||
|
@ -3022,7 +3023,7 @@ In fact, this is the kind of construction we make naturally.
|
||||||
>
|
>
|
||||||
> The first element in the sequence being evaluated to `Nothing` will stop
|
> The first element in the sequence being evaluated to `Nothing` will stop
|
||||||
> the complete evaluation.
|
> the complete evaluation.
|
||||||
> That means, you don't execute all lines.
|
> This means you don't execute all lines.
|
||||||
> You have this for free, thanks to laziness.
|
> You have this for free, thanks to laziness.
|
||||||
|
|
||||||
The `Maybe` monad proved to be useful while being a very simple example.
|
The `Maybe` monad proved to be useful while being a very simple example.
|
||||||
|
@ -3037,7 +3038,7 @@ But now a cooler example, lists.
|
||||||
|
|
||||||
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
||||||
|
|
||||||
The list monad help us to simulate non deterministic computation.
|
The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:
|
Here we go:
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -3074,8 +3075,8 @@ For the list monad, there is also a syntactical sugar:
|
||||||
4*x + 2*y < z ]
|
4*x + 2*y < z ]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
I won't list all the monads, but there is a lot of monads.
|
I won't list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for:
|
In particular, monad are very useful for:
|
||||||
|
|
||||||
- IO,
|
- IO,
|
||||||
|
@ -3088,7 +3089,9 @@ In particular, monad are very useful for:
|
||||||
If you have followed me until here, then you've done it!
|
If you have followed me until here, then you've done it!
|
||||||
You know monads[^03021301]!
|
You know monads[^03021301]!
|
||||||
|
|
||||||
[^03021301]: Well, you'll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.
|
[^03021301]: Well, you'll certainly need to practice a bit to get used to them
|
||||||
|
and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.
|
||||||
|
|
||||||
<a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a>
|
<a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a>
|
||||||
|
|
||||||
|
@ -3101,14 +3104,15 @@ It is just here to discuss some details further.
|
||||||
|
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
In the section [Infinite Structures](#infinite-structures) we saw some simple construction.
|
In the section [Infinite Structures](#infinite-structures) we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:
|
||||||
|
|
||||||
1. no duplicate node value
|
1. no duplicate node value
|
||||||
2. well ordered tree
|
2. well ordered tree
|
||||||
|
|
||||||
In this section we will try to keep the first property.
|
In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we'll discuss on how to
|
Concerning the second one, we must relax it but we'll discuss how to
|
||||||
keep it as much as possible.
|
keep it as much as possible.
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -3171,7 +3175,7 @@ Our first step is to create some pseudo-random number list:
|
||||||
shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
Just as reminder here are the definition of `treeFromList`
|
Just as a reminder, here is the definition of `treeFromList`
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3238,16 +3242,16 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
will loop forever.
|
will loop forever.
|
||||||
Simply because, it will try to access the head of `filter (<1) [2..]`.
|
Simply because it will try to access the head of `filter (<1) [2..]`.
|
||||||
But filter is not smart enought to understand that the result is the empty list.
|
But `filter` is not smart enought to understand that the result is the empty list.
|
||||||
|
|
||||||
Nonetheless, it is still a very cool example of what non strict program has to offer.
|
Nonetheless, it is still a very cool example of what non strict programs have to offer.
|
||||||
|
|
||||||
Left as an exercise to the reader:
|
Left as an exercise to the reader:
|
||||||
|
|
||||||
- Could you prove that there exists some number `n` such that `treeTakeDepth n (treeFromList shuffle)` will enter in an infinite loop.
|
- Prove the existence of a number `n` so that `treeTakeDepth n (treeFromList shuffle)` will enter an infinite loop.
|
||||||
- Find an upper bound for `n`.
|
- Find an upper bound for `n`.
|
||||||
- Prove there is no `shuffle` list such that, for any depth, the program ends.
|
- Prove there is no `shuffle` list so that, for any depth, the program ends.
|
||||||
|
|
||||||
<a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a>
|
<a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a>
|
||||||
|
|
||||||
|
|
|
@ -2100,18 +2100,19 @@ main = do
|
||||||
|
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
Congratulation to get so far!
|
Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.
|
Now, some of the really hardcore stuff can start.
|
||||||
|
|
||||||
If you are like me, you should get the functional style.
|
If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don't really understand were to start to make a real program.
|
But you also don't really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:
|
And in particular:
|
||||||
|
|
||||||
- How do you deal with effects?
|
- How do you deal with effects?
|
||||||
- Why is there a strange imperative-like notation for dealing with IO?
|
- Why is there a strange imperative-like notation for dealing with IO?
|
||||||
|
|
||||||
Be prepared, answer might be difficult to get.
|
Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.
|
But they all be very rewarding.
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a>
|
||||||
|
@ -2122,7 +2123,7 @@ But they all be very rewarding.
|
||||||
|
|
||||||
> <%=tldr%>
|
> <%=tldr%>
|
||||||
>
|
>
|
||||||
> A typical function doing `IO` look a lot like an imperative language:
|
> A typical function doing `IO` looks a lot like an imperative program:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> f :: IO a
|
> f :: IO a
|
||||||
|
@ -2141,15 +2142,15 @@ But they all be very rewarding.
|
||||||
> - `action3 :: IO c`
|
> - `action3 :: IO c`
|
||||||
> - `action4 x y :: IO a`
|
> - `action4 x y :: IO a`
|
||||||
> - `x :: b`, `y :: c`
|
> - `x :: b`, `y :: c`
|
||||||
> - Few objects have the type `IO a`, this should help you to choose.
|
> - Few objects have the type `IO a`, this should help you choose.
|
||||||
> In particular you cannot use pure function directly here.
|
> In particular you cannot use pure functions directly here.
|
||||||
> To use pure function you could do `action2 (purefunction x)` for example.
|
> To use pure functions you could do `action2 (purefunction x)` for example.
|
||||||
|
|
||||||
In this section, I will explain how to use IO, not how they work.
|
In this section, I will explain how to use IO, not how it works.
|
||||||
You'll see how Haskell separate pure from impure part of the program.
|
You'll see how Haskell separates the pure from the impure parts of the program.
|
||||||
|
|
||||||
Don't stop because you're trying to understand the details of the syntax.
|
Don't stop because you're trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.
|
Answers will come in the next section.
|
||||||
|
|
||||||
What to achieve?
|
What to achieve?
|
||||||
|
|
||||||
|
@ -2176,7 +2177,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Or more interestingly, we remark each expression in the `do` block has a type of `IO a`.
|
Or more interestingly, we note that each expression in the `do` block has a type of `IO a`.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -2185,7 +2186,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
We should also remark the effect of the `<-` symbol.
|
We should also pay attention to the effect of the `<-` symbol.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
do
|
do
|
||||||
|
@ -2194,8 +2195,8 @@ do
|
||||||
|
|
||||||
If `something :: IO a` then `x :: a`.
|
If `something :: IO a` then `x :: a`.
|
||||||
|
|
||||||
Another important remark to use `IO`.
|
Another important note about using `IO`.
|
||||||
All line in a do block must have one of the two forms:
|
All lines in a do block must be of one of the two forms:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
action1 :: IO a
|
action1 :: IO a
|
||||||
|
@ -2210,14 +2211,14 @@ value <- action2 -- where
|
||||||
-- value :: b
|
-- value :: b
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
These two kind of line will correspond to two different way of sequencing actions.
|
These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.
|
The meaning of this sentence should be clearer by the end of the next section.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a>
|
||||||
|
|
||||||
Now let's see how this behave.
|
Now let's see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let's try:
|
Let's try:
|
||||||
|
|
||||||
|
@ -2231,7 +2232,7 @@ Let's try:
|
||||||
Argh! An evil error message and a crash!
|
Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.
|
The first evolution will be to answer with a more friendly message.
|
||||||
|
|
||||||
For this, we must detect, something went wrong.
|
In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type `Maybe`.
|
Use the type `Maybe`.
|
||||||
It is a very common type in Haskell.
|
It is a very common type in Haskell.
|
||||||
|
@ -2241,7 +2242,7 @@ It is a very common type in Haskell.
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
What is this thing? Maybe is a type which takes one parameter.
|
What is this thing? `Maybe` is a type which takes one parameter.
|
||||||
Its definition is:
|
Its definition is:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -2291,32 +2292,33 @@ main = do
|
||||||
Nothing -> error "Bad format. Good Bye."
|
Nothing -> error "Bad format. Good Bye."
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
In case of error, we prompt a nice error message.
|
In case of error, we display a nice error message.
|
||||||
|
|
||||||
Remark the type of each expression in the main's do block remains of the form `IO a`.
|
Note that the type of each expression in the main's do block remains of the form `IO a`.
|
||||||
The only strange construction is `error`.
|
The only strange construction is `error`.
|
||||||
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
||||||
|
|
||||||
One very important thing to note is the type of all the defined function.
|
One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains `IO` in its type: `main`.
|
There is only one function which contains `IO` in its type: `main`.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use `getListFromString` which is pure.
|
But main uses `getListFromString` which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.
|
||||||
|
|
||||||
Why purity matters?
|
Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:
|
I certainly forget many advantages, but the three main reasons are:
|
||||||
|
|
||||||
- It is far easier to think about pure code than impure one.
|
- It is far easier to think about pure code than impure one.
|
||||||
- Purity protect you from all hard to reproduce bugs due to border effects.
|
- Purity protects you from all the hard to reproduce bugs due to side effects.
|
||||||
- You can evaluate pure functions in any order or in parallel without risk.
|
- You can evaluate pure functions in any order or in parallel without risk.
|
||||||
|
|
||||||
This is why, you should generally put as most code as possible in pure functions.
|
This is why you should generally put as most code as possible inside pure functions.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a>
|
||||||
|
|
||||||
Our next evolution will be to ask the user again and again until it enters a valid answer.
|
Our next evolution will be to prompt the user again and again until she enters a valid answer.
|
||||||
|
|
||||||
We keep the first part:
|
We keep the first part:
|
||||||
|
|
||||||
|
@ -2332,7 +2334,7 @@ getListFromString :: String -> Maybe [Integer]
|
||||||
getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
Now, we create a function which will ask the user for an integer list
|
Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.
|
until the input is right.
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -2348,14 +2350,14 @@ askUser = do
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
This function is of type `IO [Integer]`.
|
This function is of type `IO [Integer]`.
|
||||||
Such a type means, that we retrieved a value of type `[Integer]` through some IO actions.
|
Such a type means that we retrieved a value of type `[Integer]` through some IO actions.
|
||||||
Some people might explain while waving their hands:
|
Some people might explain while waving their hands:
|
||||||
|
|
||||||
> «This is an `[Integer]` inside an `IO`»
|
> «This is an `[Integer]` inside an `IO`»
|
||||||
|
|
||||||
If you want to understand the details behind all of this, you'll have to read the next section.
|
If you want to understand the details behind all of this, you'll have to read the next section.
|
||||||
But sincerely, if you just want to _use_ IO.
|
But sincerely, if you just want to _use_ IO.
|
||||||
Just exercise a little and remember to think about the type.
|
Just practice a little and remember to think about the type.
|
||||||
|
|
||||||
Finally our main function is quite simpler:
|
Finally our main function is quite simpler:
|
||||||
|
|
||||||
|
@ -2368,21 +2370,21 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
We have finished with our introduction to `IO`.
|
We have finished with our introduction to `IO`.
|
||||||
This was quite a fast. Here are the main things to remind:
|
This was quite fast. Here are the main things to remember:
|
||||||
|
|
||||||
- in the `do` bloc, each expression must have the type `IO a`.
|
- in the `do` bloc, each expression must have the type `IO a`.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, `getLine`, `print`, `putStrLn`, etc...
|
For example, `getLine`, `print`, `putStrLn`, etc...
|
||||||
- Try to externalize the pure function as much as possible.
|
- Try to externalize the pure functions as much as possible.
|
||||||
- the `IO a` type means: an IO _action_ which return an element of type `a`.
|
- the `IO a` type means: an IO _action_ which returns an element of type `a`.
|
||||||
`IO` represent action; under the hood, `IO a` is the type of a function.
|
`IO` represents actions; under the hood, `IO a` is the type of a function.
|
||||||
Read the next section if you are curious.
|
Read the next section if you are curious.
|
||||||
|
|
||||||
If you exercise a bit, you should be able to _use_ `IO`.
|
If you practice a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> _Exercises_:
|
> _Exercises_:
|
||||||
>
|
>
|
||||||
> - Make a program that sum all its argument. Hint: use the function `getArgs`.
|
> - Make a program that sums all of its arguments. Hint: use the function `getArgs`.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
|
@ -2392,15 +2394,15 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> Here is a <%=tldr%> for this section.
|
> Here is a <%=tldr%> for this section.
|
||||||
>
|
>
|
||||||
> To separate pure from impure part,
|
> To separate pure and impure parts,
|
||||||
> the main is defined as a function
|
> `main` is defined as a function
|
||||||
> which modify the state of the world
|
> which modifies the state of the world
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main :: World -> World
|
> main :: World -> World
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> A function is granted to have side effect only if it gets this value.
|
> A function is guaranteed to have side effects only if it has this type.
|
||||||
> But look at a typical main function:
|
> But look at a typical main function:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -2412,17 +2414,17 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
||||||
> which must be passed to the next action.
|
> which must be passed on to the next action.
|
||||||
>
|
>
|
||||||
> We create a function `bind` or `(>>=)`.
|
> We create a function `bind` or `(>>=)`.
|
||||||
> With `bind` we need no more temporary name.
|
> With `bind` we don't need temporary names anymore.
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main =
|
> main =
|
||||||
> action1 >>= action2 >>= action3 >>= action4
|
> action1 >>= action2 >>= action3 >>= action4
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> Bonus: Haskell has a syntactical sugar for us:
|
> Bonus: Haskell has syntactical sugar for us:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main = do
|
> main = do
|
||||||
|
@ -2432,11 +2434,11 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
> action4 v3
|
> action4 v3
|
||||||
> ~~~
|
> ~~~
|
||||||
|
|
||||||
Why did we used some strange syntax, and what exactly is this `IO` type.
|
Why did we use this strange syntax, and what exactly is this `IO` type?
|
||||||
It looks a bit like magic.
|
It looks a bit like magic.
|
||||||
|
|
||||||
For now let's just forget about all the pure part of our program, and focus
|
For now let's just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:
|
on the impure parts:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: IO [Integer]
|
askUser :: IO [Integer]
|
||||||
|
@ -2455,33 +2457,33 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First remark; it looks like an imperative structure.
|
First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a `while` in Haskell.
|
For example, if you wish you could create a `while` in Haskell.
|
||||||
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
||||||
|
|
||||||
But, you should had remarked the notation is a bit unusual.
|
But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.
|
Here is why, in detail.
|
||||||
|
|
||||||
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.
|
The fact that a file exists or not can be seen as different states of the world.
|
||||||
|
|
||||||
For Haskell this state is not hidden.
|
For Haskell this state is not hidden.
|
||||||
It is explicitly said `main` is a function that _potentially_ change the state of the world.
|
It is explicitly said `main` is a function that _potentially_ changes the state of the world.
|
||||||
It's type is then something like:
|
Its type is then something like:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
main :: World -> World
|
main :: World -> World
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not all function could have access to this variable.
|
Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn't provided to should be pure[^032001].
|
Functions to which the world variable isn't provided are pure[^032001].
|
||||||
|
|
||||||
[^032001]: There are some _unsafe_ exception to this rule. But you shouldn't see such usage on a real application except might be for some debugging purpose.
|
[^032001]: There are some _unsafe_ exceptions to this rule. But you shouldn't see such use on a real application except maybe for debugging purpose.
|
||||||
|
|
||||||
Haskell consider the state of the world is an input variable for `main`.
|
Haskell considers the state of the world as an input variable to `main`.
|
||||||
But the real type of main is closer to this one[^032002]:
|
But the real type of main is closer to this one[^032002]:
|
||||||
|
|
||||||
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
||||||
|
@ -2502,17 +2504,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First, we remark, that all function which have side effect must have the type:
|
First, we note that all functions which have side effects must have the type:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
World -> (a,World)
|
World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Where `a` is the type of result.
|
Where `a` is the type of the result.
|
||||||
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
||||||
|
|
||||||
Another thing to remark is the trick to fix the order of evaluation.
|
Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate `f a b`, you generally have many choices:
|
In Haskell, in order to evaluate `f a b`, you have many choices:
|
||||||
|
|
||||||
- first eval `a` then `b` then `f a b`
|
- first eval `a` then `b` then `f a b`
|
||||||
- first eval `b` then `a` then `f a b`.
|
- first eval `b` then `a` then `f a b`.
|
||||||
|
@ -2533,7 +2535,7 @@ Under the hood, `print` will evaluate as:
|
||||||
- evaluate as `((),new world id)`.
|
- evaluate as `((),new world id)`.
|
||||||
|
|
||||||
Now, if you look at the style of the main function, it is clearly awkward.
|
Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let's try to make the same to the askUser function:
|
Let's try to do the same to the askUser function:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: World -> ([Integer],World)
|
askUser :: World -> ([Integer],World)
|
||||||
|
@ -2568,9 +2570,9 @@ askUser w0 =
|
||||||
This is similar, but awkward.
|
This is similar, but awkward.
|
||||||
Look at all these temporary `w?` names.
|
Look at all these temporary `w?` names.
|
||||||
|
|
||||||
The lesson, is, naive IO implementation in Pure functional language is awkward!
|
The lesson, is, naive IO implementation in Pure functional languages is awkward!
|
||||||
|
|
||||||
Fortunately, some have found a better way to handle this problem.
|
Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:
|
Each line is of the form:
|
||||||
|
|
||||||
|
@ -2586,8 +2588,7 @@ Each function `f` must have a type similar to:
|
||||||
f :: World -> (a,World)
|
f :: World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not only this, but we can also remark we use them always
|
Not only this, but we can also note that we always follow the same usage pattern:
|
||||||
with the following general pattern:
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (y,w1) = action1 w0 in
|
let (y,w1) = action1 w0 in
|
||||||
|
@ -2596,7 +2597,7 @@ let (t,w3) = action3 w2 in
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Each action can take 0 to some parameters.
|
Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.
|
And in particular, each action can take a parameter from the result of a line above.
|
||||||
|
|
||||||
For example, we could also have:
|
For example, we could also have:
|
||||||
|
@ -2610,7 +2611,7 @@ let (_,w3) = action3 x z w2 in
|
||||||
|
|
||||||
And of course `actionN w :: (World) -> (a,World)`.
|
And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
> IMPORTANT, there are only two important pattern for us:
|
> IMPORTANT, there are only two important patterns to consider:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> let (x,w1) = action1 w0 in
|
> let (x,w1) = action1 w0 in
|
||||||
|
@ -2626,7 +2627,7 @@ And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
||||||
|
|
||||||
Now, we will make a magic trick.
|
Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol "disappear".
|
We will make the temporary world symbol "disappear".
|
||||||
We will `bind` the two lines.
|
We will `bind` the two lines.
|
||||||
Let's define the `bind` function.
|
Let's define the `bind` function.
|
||||||
|
@ -2652,18 +2653,18 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
`getLine` is an IO action which take a world as parameter and return a couple `(String,World)`.
|
`getLine` is an IO action which takes a world as parameter and returns a couple `(String,World)`.
|
||||||
Which can be said as: `getLine` is of type `IO String`.
|
Which can be summarized as: `getLine` is of type `IO String`.
|
||||||
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
||||||
|
|
||||||
The function `print` is also interresting.
|
The function `print` is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type `((),World)`.
|
It then returns a couple of type `((),World)`.
|
||||||
This means it changes the world state, but don't give anymore data.
|
This means it changes the state of the world, but doesn't yield anymore data.
|
||||||
|
|
||||||
This type help us simplify the type of `bind`:
|
This type helps us simplify the type of `bind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
bind :: IO a
|
bind :: IO a
|
||||||
|
@ -2689,7 +2690,7 @@ action2 :: a -> IO b
|
||||||
(y,w2) :: IO b
|
(y,w2) :: IO b
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Doesn't seem familiar?
|
Doesn't it seem familiar?
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -2699,7 +2700,7 @@ Doesn't seem familiar?
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
The idea is to hide the World argument with this function. Let's go:
|
The idea is to hide the World argument with this function. Let's go:
|
||||||
As example imagine if we wanted to simulate:
|
As an example imagine if we wanted to simulate:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -2714,7 +2715,7 @@ Now, using the bind function:
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
As print is of type (World -> ((),World)), we know res = () (null type).
|
As print is of type (World -> ((),World)), we know res = () (null type).
|
||||||
If you didn't saw what was magic here, let's try with three lines this time.
|
If you didn't see what was magic here, let's try with three lines this time.
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -2731,8 +2732,8 @@ Which is equivalent to:
|
||||||
print (line1 ++ line2)))
|
print (line1 ++ line2)))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Didn't you remark something?
|
Didn't you notice something?
|
||||||
Yes, there isn't anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is _MA_. _GIC_.
|
This is _MA_. _GIC_.
|
||||||
|
|
||||||
We can use a better notation.
|
We can use a better notation.
|
||||||
|
@ -2747,7 +2748,7 @@ Let's use `(>>=)` instead of `bind`.
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Ho Ho Ho! Happy Christmas Everyone!
|
Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:
|
Haskell has made syntactical sugar for us:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
do
|
do
|
||||||
|
@ -2768,8 +2769,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
||||||
|
|
||||||
But what for line not using the `<-`?
|
But what about the lines not using the `<-`?
|
||||||
Easy another function `blindBind`:
|
Easy, another function `blindBind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
blindBind :: IO a -> IO b -> IO b
|
blindBind :: IO a -> IO b -> IO b
|
||||||
|
@ -2777,7 +2778,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
I didn't simplified this definition for clarity purpose.
|
I didn't simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we'll use the `(>>)` operator.
|
Of course we can use a better notation, we'll use the `(>>)` operator.
|
||||||
|
|
||||||
And
|
And
|
||||||
|
@ -2804,7 +2805,7 @@ putInIO :: a -> IO a
|
||||||
putInIO x = IO (\w -> (x,w))
|
putInIO x = IO (\w -> (x,w))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
This is the general way to put pure value inside the "IO context".
|
This is the general way to put pure values inside the "IO context".
|
||||||
The general name for `putInIO` is `return`.
|
The general name for `putInIO` is `return`.
|
||||||
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
||||||
|
|
||||||
|
@ -2855,7 +2856,7 @@ main = askUser >>=
|
||||||
\list -> print $ sum list
|
\list -> print $ sum list
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
You can compile this code to verify it continues to work.
|
You can compile this code to verify it keeps working.
|
||||||
|
|
||||||
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
||||||
|
@ -2865,11 +2866,11 @@ Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<%= blogimage("dali_reve.jpg","Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
<%= blogimage("dali_reve.jpg","Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
||||||
|
|
||||||
Now the secret can be revealed: `IO` is a _monad_.
|
Now the secret can be revealed: `IO` is a _monad_.
|
||||||
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.
|
But mainly, you have access to a coding pattern which will ease the flow of your code.
|
||||||
|
|
||||||
> **Important remarks**:
|
> **Important remarks**:
|
||||||
>
|
>
|
||||||
|
@ -2900,13 +2901,13 @@ class Monad m where
|
||||||
>
|
>
|
||||||
> - the keyword `class` is not your friend.
|
> - the keyword `class` is not your friend.
|
||||||
> A Haskell class is _not_ a class like in object model.
|
> A Haskell class is _not_ a class like in object model.
|
||||||
> A Haskell class has a lot similarities with Java interfaces.
|
> A Haskell class has a lot of similarities with Java interfaces.
|
||||||
> A better word should have been `typeclass`.
|
> A better word should have been `typeclass`.
|
||||||
> That means a set of types.
|
> That means a set of types.
|
||||||
> For a type to belong to a class, all function of the class must be provided for this type.
|
> For a type to belong to a class, all functions of the class must be provided for this type.
|
||||||
> - In this particular example of type class, the type `m` must be a type that take an argument.
|
> - In this particular example of type class, the type `m` must be a type that takes an argument.
|
||||||
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
||||||
> - To be a useful monad, your function must obey some rule.
|
> - To be a useful monad, your function must obey some rules.
|
||||||
> If your construction does not obey these rules strange things might happens:
|
> If your construction does not obey these rules strange things might happens:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -2917,13 +2918,13 @@ class Monad m where
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
There exists a lot of different type that are instance of `Monad`.
|
There are a lot of different types that are instance of `Monad`.
|
||||||
One of the easiest to describe is `Maybe`.
|
One of the easiest to describe is `Maybe`.
|
||||||
If you have a sequence of `Maybe` values, you could use monad to manipulate them.
|
If you have a sequence of `Maybe` values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep `if..then..else..` constructions.
|
It is particularly useful to remove very deep `if..then..else..` constructions.
|
||||||
|
|
||||||
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.
|
if you can afford to follow a list of operations without being negative.
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -2963,7 +2964,7 @@ main = do
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a>
|
<hr/><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a>
|
||||||
|
|
||||||
Now, let's make it better using Maybe and the fact it is a Monad
|
Now, let's make it better using Maybe and the fact that it is a Monad
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3019,7 +3020,7 @@ main = do
|
||||||
print $ eligible 299 -- Nothing
|
print $ eligible 299 -- Nothing
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
We have proved Monad are nice to make our code more elegant.
|
We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for `Maybe` can be used
|
Note this idea of code organization, in particular for `Maybe` can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.
|
In fact, this is the kind of construction we make naturally.
|
||||||
|
@ -3028,7 +3029,7 @@ In fact, this is the kind of construction we make naturally.
|
||||||
>
|
>
|
||||||
> The first element in the sequence being evaluated to `Nothing` will stop
|
> The first element in the sequence being evaluated to `Nothing` will stop
|
||||||
> the complete evaluation.
|
> the complete evaluation.
|
||||||
> That means, you don't execute all lines.
|
> This means you don't execute all lines.
|
||||||
> You have this for free, thanks to laziness.
|
> You have this for free, thanks to laziness.
|
||||||
|
|
||||||
The `Maybe` monad proved to be useful while being a very simple example.
|
The `Maybe` monad proved to be useful while being a very simple example.
|
||||||
|
@ -3043,7 +3044,7 @@ But now a cooler example, lists.
|
||||||
|
|
||||||
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
||||||
|
|
||||||
The list monad help us to simulate non deterministic computation.
|
The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:
|
Here we go:
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -3080,8 +3081,8 @@ For the list monad, there is also a syntactical sugar:
|
||||||
4*x + 2*y < z ]
|
4*x + 2*y < z ]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
I won't list all the monads, but there is a lot of monads.
|
I won't list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for:
|
In particular, monad are very useful for:
|
||||||
|
|
||||||
- IO,
|
- IO,
|
||||||
|
@ -3094,7 +3095,9 @@ In particular, monad are very useful for:
|
||||||
If you have followed me until here, then you've done it!
|
If you have followed me until here, then you've done it!
|
||||||
You know monads[^03021301]!
|
You know monads[^03021301]!
|
||||||
|
|
||||||
[^03021301]: Well, you'll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.
|
[^03021301]: Well, you'll certainly need to practice a bit to get used to them
|
||||||
|
and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.
|
||||||
|
|
||||||
<a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a>
|
<a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a>
|
||||||
|
|
||||||
|
@ -3107,14 +3110,15 @@ It is just here to discuss some details further.
|
||||||
|
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
In the section [Infinite Structures](#infinite-structures) we saw some simple construction.
|
In the section [Infinite Structures](#infinite-structures) we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:
|
||||||
|
|
||||||
1. no duplicate node value
|
1. no duplicate node value
|
||||||
2. well ordered tree
|
2. well ordered tree
|
||||||
|
|
||||||
In this section we will try to keep the first property.
|
In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we'll discuss on how to
|
Concerning the second one, we must relax it but we'll discuss how to
|
||||||
keep it as much as possible.
|
keep it as much as possible.
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -3177,7 +3181,7 @@ Our first step is to create some pseudo-random number list:
|
||||||
shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
Just as reminder here are the definition of `treeFromList`
|
Just as a reminder, here is the definition of `treeFromList`
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3244,16 +3248,16 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
will loop forever.
|
will loop forever.
|
||||||
Simply because, it will try to access the head of `filter (<1) [2..]`.
|
Simply because it will try to access the head of `filter (<1) [2..]`.
|
||||||
But filter is not smart enought to understand that the result is the empty list.
|
But `filter` is not smart enought to understand that the result is the empty list.
|
||||||
|
|
||||||
Nonetheless, it is still a very cool example of what non strict program has to offer.
|
Nonetheless, it is still a very cool example of what non strict programs have to offer.
|
||||||
|
|
||||||
Left as an exercise to the reader:
|
Left as an exercise to the reader:
|
||||||
|
|
||||||
- Could you prove that there exists some number `n` such that `treeTakeDepth n (treeFromList shuffle)` will enter in an infinite loop.
|
- Prove the existence of a number `n` so that `treeTakeDepth n (treeFromList shuffle)` will enter an infinite loop.
|
||||||
- Find an upper bound for `n`.
|
- Find an upper bound for `n`.
|
||||||
- Prove there is no `shuffle` list such that, for any depth, the program ends.
|
- Prove there is no `shuffle` list so that, for any depth, the program ends.
|
||||||
|
|
||||||
<a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a>
|
<a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a>
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
# <% end %>
|
# <% end %>
|
||||||
# Pour remplir à la fois le texte et le sommaire
|
# Pour remplir à la fois le texte et le sommaire
|
||||||
|
|
||||||
include Nanoc3::Helpers::Capturing
|
# include Nanoc3::Helpers::Capturing
|
||||||
include Nanoc3::Helpers::LinkTo
|
include Nanoc3::Helpers::LinkTo
|
||||||
include Nanoc3::Helpers::Blogging
|
include Nanoc3::Helpers::Blogging
|
||||||
include Nanoc3::Helpers::Text
|
include Nanoc3::Helpers::Text
|
||||||
|
|
|
@ -2153,18 +2153,19 @@ main = do
|
||||||
|
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
Congratulation to get so far!
|
Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.
|
Now, some of the really hardcore stuff can start.
|
||||||
|
|
||||||
If you are like me, you should get the functional style.
|
If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don't really understand were to start to make a real program.
|
But you also don't really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:
|
And in particular:
|
||||||
|
|
||||||
- How do you deal with effects?
|
- How do you deal with effects?
|
||||||
- Why is there a strange imperative-like notation for dealing with IO?
|
- Why is there a strange imperative-like notation for dealing with IO?
|
||||||
|
|
||||||
Be prepared, answer might be difficult to get.
|
Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.
|
But they all be very rewarding.
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong></a>
|
||||||
|
@ -2175,7 +2176,7 @@ But they all be very rewarding.
|
||||||
|
|
||||||
> <%=tldr%>
|
> <%=tldr%>
|
||||||
>
|
>
|
||||||
> A typical function doing `IO` look a lot like an imperative language:
|
> A typical function doing `IO` looks a lot like an imperative program:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> f :: IO a
|
> f :: IO a
|
||||||
|
@ -2194,15 +2195,15 @@ But they all be very rewarding.
|
||||||
> - `action3 :: IO c`
|
> - `action3 :: IO c`
|
||||||
> - `action4 x y :: IO a`
|
> - `action4 x y :: IO a`
|
||||||
> - `x :: b`, `y :: c`
|
> - `x :: b`, `y :: c`
|
||||||
> - Few objects have the type `IO a`, this should help you to choose.
|
> - Few objects have the type `IO a`, this should help you choose.
|
||||||
> In particular you cannot use pure function directly here.
|
> In particular you cannot use pure functions directly here.
|
||||||
> To use pure function you could do `action2 (purefunction x)` for example.
|
> To use pure functions you could do `action2 (purefunction x)` for example.
|
||||||
|
|
||||||
In this section, I will explain how to use IO, not how they work.
|
In this section, I will explain how to use IO, not how it works.
|
||||||
You'll see how Haskell separate pure from impure part of the program.
|
You'll see how Haskell separates the pure from the impure parts of the program.
|
||||||
|
|
||||||
Don't stop because you're trying to understand the details of the syntax.
|
Don't stop because you're trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.
|
Answers will come in the next section.
|
||||||
|
|
||||||
What to achieve?
|
What to achieve?
|
||||||
|
|
||||||
|
@ -2229,7 +2230,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Or more interestingly, we remark each expression in the `do` block has a type of `IO a`.
|
Or more interestingly, we note that each expression in the `do` block has a type of `IO a`.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -2238,7 +2239,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
We should also remark the effect of the `<-` symbol.
|
We should also pay attention to the effect of the `<-` symbol.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
do
|
do
|
||||||
|
@ -2247,8 +2248,8 @@ do
|
||||||
|
|
||||||
If `something :: IO a` then `x :: a`.
|
If `something :: IO a` then `x :: a`.
|
||||||
|
|
||||||
Another important remark to use `IO`.
|
Another important note about using `IO`.
|
||||||
All line in a do block must have one of the two forms:
|
All lines in a do block must be of one of the two forms:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
action1 :: IO a
|
action1 :: IO a
|
||||||
|
@ -2263,14 +2264,14 @@ value <- action2 -- where
|
||||||
-- value :: b
|
-- value :: b
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
These two kind of line will correspond to two different way of sequencing actions.
|
These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.
|
The meaning of this sentence should be clearer by the end of the next section.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a>
|
||||||
|
|
||||||
Now let's see how this behave.
|
Now let's see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let's try:
|
Let's try:
|
||||||
|
|
||||||
|
@ -2284,7 +2285,7 @@ Let's try:
|
||||||
Argh! An evil error message and a crash!
|
Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.
|
The first evolution will be to answer with a more friendly message.
|
||||||
|
|
||||||
For this, we must detect, something went wrong.
|
In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type `Maybe`.
|
Use the type `Maybe`.
|
||||||
It is a very common type in Haskell.
|
It is a very common type in Haskell.
|
||||||
|
@ -2294,7 +2295,7 @@ It is a very common type in Haskell.
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
What is this thing? Maybe is a type which takes one parameter.
|
What is this thing? `Maybe` is a type which takes one parameter.
|
||||||
Its definition is:
|
Its definition is:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -2344,32 +2345,33 @@ main = do
|
||||||
Nothing -> error "Bad format. Good Bye."
|
Nothing -> error "Bad format. Good Bye."
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
In case of error, we prompt a nice error message.
|
In case of error, we display a nice error message.
|
||||||
|
|
||||||
Remark the type of each expression in the main's do block remains of the form `IO a`.
|
Note that the type of each expression in the main's do block remains of the form `IO a`.
|
||||||
The only strange construction is `error`.
|
The only strange construction is `error`.
|
||||||
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
||||||
|
|
||||||
One very important thing to note is the type of all the defined function.
|
One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains `IO` in its type: `main`.
|
There is only one function which contains `IO` in its type: `main`.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use `getListFromString` which is pure.
|
But main uses `getListFromString` which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.
|
||||||
|
|
||||||
Why purity matters?
|
Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:
|
I certainly forget many advantages, but the three main reasons are:
|
||||||
|
|
||||||
- It is far easier to think about pure code than impure one.
|
- It is far easier to think about pure code than impure one.
|
||||||
- Purity protect you from all hard to reproduce bugs due to border effects.
|
- Purity protects you from all the hard to reproduce bugs due to side effects.
|
||||||
- You can evaluate pure functions in any order or in parallel without risk.
|
- You can evaluate pure functions in any order or in parallel without risk.
|
||||||
|
|
||||||
This is why, you should generally put as most code as possible in pure functions.
|
This is why you should generally put as most code as possible inside pure functions.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a>
|
<hr/><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a>
|
||||||
|
|
||||||
Our next evolution will be to ask the user again and again until it enters a valid answer.
|
Our next evolution will be to prompt the user again and again until she enters a valid answer.
|
||||||
|
|
||||||
We keep the first part:
|
We keep the first part:
|
||||||
|
|
||||||
|
@ -2385,7 +2387,7 @@ getListFromString :: String -> Maybe [Integer]
|
||||||
getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
Now, we create a function which will ask the user for an integer list
|
Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.
|
until the input is right.
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -2401,14 +2403,14 @@ askUser = do
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
This function is of type `IO [Integer]`.
|
This function is of type `IO [Integer]`.
|
||||||
Such a type means, that we retrieved a value of type `[Integer]` through some IO actions.
|
Such a type means that we retrieved a value of type `[Integer]` through some IO actions.
|
||||||
Some people might explain while waving their hands:
|
Some people might explain while waving their hands:
|
||||||
|
|
||||||
> «This is an `[Integer]` inside an `IO`»
|
> «This is an `[Integer]` inside an `IO`»
|
||||||
|
|
||||||
If you want to understand the details behind all of this, you'll have to read the next section.
|
If you want to understand the details behind all of this, you'll have to read the next section.
|
||||||
But sincerely, if you just want to _use_ IO.
|
But sincerely, if you just want to _use_ IO.
|
||||||
Just exercise a little and remember to think about the type.
|
Just practice a little and remember to think about the type.
|
||||||
|
|
||||||
Finally our main function is quite simpler:
|
Finally our main function is quite simpler:
|
||||||
|
|
||||||
|
@ -2421,21 +2423,21 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
We have finished with our introduction to `IO`.
|
We have finished with our introduction to `IO`.
|
||||||
This was quite a fast. Here are the main things to remind:
|
This was quite fast. Here are the main things to remember:
|
||||||
|
|
||||||
- in the `do` bloc, each expression must have the type `IO a`.
|
- in the `do` bloc, each expression must have the type `IO a`.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, `getLine`, `print`, `putStrLn`, etc...
|
For example, `getLine`, `print`, `putStrLn`, etc...
|
||||||
- Try to externalize the pure function as much as possible.
|
- Try to externalize the pure functions as much as possible.
|
||||||
- the `IO a` type means: an IO _action_ which return an element of type `a`.
|
- the `IO a` type means: an IO _action_ which returns an element of type `a`.
|
||||||
`IO` represent action; under the hood, `IO a` is the type of a function.
|
`IO` represents actions; under the hood, `IO a` is the type of a function.
|
||||||
Read the next section if you are curious.
|
Read the next section if you are curious.
|
||||||
|
|
||||||
If you exercise a bit, you should be able to _use_ `IO`.
|
If you practice a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> _Exercises_:
|
> _Exercises_:
|
||||||
>
|
>
|
||||||
> - Make a program that sum all its argument. Hint: use the function `getArgs`.
|
> - Make a program that sums all of its arguments. Hint: use the function `getArgs`.
|
||||||
|
|
||||||
<a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a>
|
<a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong> </a>
|
||||||
|
|
||||||
|
@ -2445,15 +2447,15 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> Here is a <%=tldr%> for this section.
|
> Here is a <%=tldr%> for this section.
|
||||||
>
|
>
|
||||||
> To separate pure from impure part,
|
> To separate pure and impure parts,
|
||||||
> the main is defined as a function
|
> `main` is defined as a function
|
||||||
> which modify the state of the world
|
> which modifies the state of the world
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main :: World -> World
|
> main :: World -> World
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> A function is granted to have side effect only if it gets this value.
|
> A function is guaranteed to have side effects only if it has this type.
|
||||||
> But look at a typical main function:
|
> But look at a typical main function:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -2465,17 +2467,17 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
||||||
> which must be passed to the next action.
|
> which must be passed on to the next action.
|
||||||
>
|
>
|
||||||
> We create a function `bind` or `(>>=)`.
|
> We create a function `bind` or `(>>=)`.
|
||||||
> With `bind` we need no more temporary name.
|
> With `bind` we don't need temporary names anymore.
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main =
|
> main =
|
||||||
> action1 >>= action2 >>= action3 >>= action4
|
> action1 >>= action2 >>= action3 >>= action4
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> Bonus: Haskell has a syntactical sugar for us:
|
> Bonus: Haskell has syntactical sugar for us:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main = do
|
> main = do
|
||||||
|
@ -2485,11 +2487,11 @@ If you exercise a bit, you should be able to _use_ `IO`.
|
||||||
> action4 v3
|
> action4 v3
|
||||||
> ~~~
|
> ~~~
|
||||||
|
|
||||||
Why did we used some strange syntax, and what exactly is this `IO` type.
|
Why did we use this strange syntax, and what exactly is this `IO` type?
|
||||||
It looks a bit like magic.
|
It looks a bit like magic.
|
||||||
|
|
||||||
For now let's just forget about all the pure part of our program, and focus
|
For now let's just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:
|
on the impure parts:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: IO [Integer]
|
askUser :: IO [Integer]
|
||||||
|
@ -2508,33 +2510,33 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First remark; it looks like an imperative structure.
|
First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a `while` in Haskell.
|
For example, if you wish you could create a `while` in Haskell.
|
||||||
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
||||||
|
|
||||||
But, you should had remarked the notation is a bit unusual.
|
But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.
|
Here is why, in detail.
|
||||||
|
|
||||||
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.
|
The fact that a file exists or not can be seen as different states of the world.
|
||||||
|
|
||||||
For Haskell this state is not hidden.
|
For Haskell this state is not hidden.
|
||||||
It is explicitly said `main` is a function that _potentially_ change the state of the world.
|
It is explicitly said `main` is a function that _potentially_ changes the state of the world.
|
||||||
It's type is then something like:
|
Its type is then something like:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
main :: World -> World
|
main :: World -> World
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not all function could have access to this variable.
|
Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn't provided to should be pure[^032001].
|
Functions to which the world variable isn't provided are pure[^032001].
|
||||||
|
|
||||||
[^032001]: There are some _unsafe_ exception to this rule. But you shouldn't see such usage on a real application except might be for some debugging purpose.
|
[^032001]: There are some _unsafe_ exceptions to this rule. But you shouldn't see such use on a real application except maybe for debugging purpose.
|
||||||
|
|
||||||
Haskell consider the state of the world is an input variable for `main`.
|
Haskell considers the state of the world as an input variable to `main`.
|
||||||
But the real type of main is closer to this one[^032002]:
|
But the real type of main is closer to this one[^032002]:
|
||||||
|
|
||||||
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
||||||
|
@ -2555,17 +2557,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First, we remark, that all function which have side effect must have the type:
|
First, we note that all functions which have side effects must have the type:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
World -> (a,World)
|
World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Where `a` is the type of result.
|
Where `a` is the type of the result.
|
||||||
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
||||||
|
|
||||||
Another thing to remark is the trick to fix the order of evaluation.
|
Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate `f a b`, you generally have many choices:
|
In Haskell, in order to evaluate `f a b`, you have many choices:
|
||||||
|
|
||||||
- first eval `a` then `b` then `f a b`
|
- first eval `a` then `b` then `f a b`
|
||||||
- first eval `b` then `a` then `f a b`.
|
- first eval `b` then `a` then `f a b`.
|
||||||
|
@ -2586,7 +2588,7 @@ Under the hood, `print` will evaluate as:
|
||||||
- evaluate as `((),new world id)`.
|
- evaluate as `((),new world id)`.
|
||||||
|
|
||||||
Now, if you look at the style of the main function, it is clearly awkward.
|
Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let's try to make the same to the askUser function:
|
Let's try to do the same to the askUser function:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: World -> ([Integer],World)
|
askUser :: World -> ([Integer],World)
|
||||||
|
@ -2621,9 +2623,9 @@ askUser w0 =
|
||||||
This is similar, but awkward.
|
This is similar, but awkward.
|
||||||
Look at all these temporary `w?` names.
|
Look at all these temporary `w?` names.
|
||||||
|
|
||||||
The lesson, is, naive IO implementation in Pure functional language is awkward!
|
The lesson, is, naive IO implementation in Pure functional languages is awkward!
|
||||||
|
|
||||||
Fortunately, some have found a better way to handle this problem.
|
Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:
|
Each line is of the form:
|
||||||
|
|
||||||
|
@ -2639,8 +2641,7 @@ Each function `f` must have a type similar to:
|
||||||
f :: World -> (a,World)
|
f :: World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not only this, but we can also remark we use them always
|
Not only this, but we can also note that we always follow the same usage pattern:
|
||||||
with the following general pattern:
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (y,w1) = action1 w0 in
|
let (y,w1) = action1 w0 in
|
||||||
|
@ -2649,7 +2650,7 @@ let (t,w3) = action3 w2 in
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Each action can take 0 to some parameters.
|
Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.
|
And in particular, each action can take a parameter from the result of a line above.
|
||||||
|
|
||||||
For example, we could also have:
|
For example, we could also have:
|
||||||
|
@ -2663,7 +2664,7 @@ let (_,w3) = action3 x z w2 in
|
||||||
|
|
||||||
And of course `actionN w :: (World) -> (a,World)`.
|
And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
> IMPORTANT, there are only two important pattern for us:
|
> IMPORTANT, there are only two important patterns to consider:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> let (x,w1) = action1 w0 in
|
> let (x,w1) = action1 w0 in
|
||||||
|
@ -2679,7 +2680,7 @@ And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
||||||
|
|
||||||
Now, we will make a magic trick.
|
Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol "disappear".
|
We will make the temporary world symbol "disappear".
|
||||||
We will `bind` the two lines.
|
We will `bind` the two lines.
|
||||||
Let's define the `bind` function.
|
Let's define the `bind` function.
|
||||||
|
@ -2705,18 +2706,18 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
`getLine` is an IO action which take a world as parameter and return a couple `(String,World)`.
|
`getLine` is an IO action which takes a world as parameter and returns a couple `(String,World)`.
|
||||||
Which can be said as: `getLine` is of type `IO String`.
|
Which can be summarized as: `getLine` is of type `IO String`.
|
||||||
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
||||||
|
|
||||||
The function `print` is also interresting.
|
The function `print` is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type `((),World)`.
|
It then returns a couple of type `((),World)`.
|
||||||
This means it changes the world state, but don't give anymore data.
|
This means it changes the state of the world, but doesn't yield anymore data.
|
||||||
|
|
||||||
This type help us simplify the type of `bind`:
|
This type helps us simplify the type of `bind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
bind :: IO a
|
bind :: IO a
|
||||||
|
@ -2742,7 +2743,7 @@ action2 :: a -> IO b
|
||||||
(y,w2) :: IO b
|
(y,w2) :: IO b
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Doesn't seem familiar?
|
Doesn't it seem familiar?
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -2752,7 +2753,7 @@ Doesn't seem familiar?
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
The idea is to hide the World argument with this function. Let's go:
|
The idea is to hide the World argument with this function. Let's go:
|
||||||
As example imagine if we wanted to simulate:
|
As an example imagine if we wanted to simulate:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -2767,7 +2768,7 @@ Now, using the bind function:
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
As print is of type (World -> ((),World)), we know res = () (null type).
|
As print is of type (World -> ((),World)), we know res = () (null type).
|
||||||
If you didn't saw what was magic here, let's try with three lines this time.
|
If you didn't see what was magic here, let's try with three lines this time.
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -2784,8 +2785,8 @@ Which is equivalent to:
|
||||||
print (line1 ++ line2)))
|
print (line1 ++ line2)))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Didn't you remark something?
|
Didn't you notice something?
|
||||||
Yes, there isn't anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is _MA_. _GIC_.
|
This is _MA_. _GIC_.
|
||||||
|
|
||||||
We can use a better notation.
|
We can use a better notation.
|
||||||
|
@ -2800,7 +2801,7 @@ Let's use `(>>=)` instead of `bind`.
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Ho Ho Ho! Happy Christmas Everyone!
|
Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:
|
Haskell has made syntactical sugar for us:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
do
|
do
|
||||||
|
@ -2821,8 +2822,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
||||||
|
|
||||||
But what for line not using the `<-`?
|
But what about the lines not using the `<-`?
|
||||||
Easy another function `blindBind`:
|
Easy, another function `blindBind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
blindBind :: IO a -> IO b -> IO b
|
blindBind :: IO a -> IO b -> IO b
|
||||||
|
@ -2830,7 +2831,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
I didn't simplified this definition for clarity purpose.
|
I didn't simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we'll use the `(>>)` operator.
|
Of course we can use a better notation, we'll use the `(>>)` operator.
|
||||||
|
|
||||||
And
|
And
|
||||||
|
@ -2857,7 +2858,7 @@ putInIO :: a -> IO a
|
||||||
putInIO x = IO (\w -> (x,w))
|
putInIO x = IO (\w -> (x,w))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
This is the general way to put pure value inside the "IO context".
|
This is the general way to put pure values inside the "IO context".
|
||||||
The general name for `putInIO` is `return`.
|
The general name for `putInIO` is `return`.
|
||||||
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
||||||
|
|
||||||
|
@ -2908,7 +2909,7 @@ main = askUser >>=
|
||||||
\list -> print $ sum list
|
\list -> print $ sum list
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
You can compile this code to verify it continues to work.
|
You can compile this code to verify it keeps working.
|
||||||
|
|
||||||
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
||||||
|
@ -2918,11 +2919,11 @@ Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<%= blogimage("dali_reve.jpg","Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
<%= blogimage("dali_reve.jpg","Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
||||||
|
|
||||||
Now the secret can be revealed: `IO` is a _monad_.
|
Now the secret can be revealed: `IO` is a _monad_.
|
||||||
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.
|
But mainly, you have access to a coding pattern which will ease the flow of your code.
|
||||||
|
|
||||||
> **Important remarks**:
|
> **Important remarks**:
|
||||||
>
|
>
|
||||||
|
@ -2953,13 +2954,13 @@ class Monad m where
|
||||||
>
|
>
|
||||||
> - the keyword `class` is not your friend.
|
> - the keyword `class` is not your friend.
|
||||||
> A Haskell class is _not_ a class like in object model.
|
> A Haskell class is _not_ a class like in object model.
|
||||||
> A Haskell class has a lot similarities with Java interfaces.
|
> A Haskell class has a lot of similarities with Java interfaces.
|
||||||
> A better word should have been `typeclass`.
|
> A better word should have been `typeclass`.
|
||||||
> That means a set of types.
|
> That means a set of types.
|
||||||
> For a type to belong to a class, all function of the class must be provided for this type.
|
> For a type to belong to a class, all functions of the class must be provided for this type.
|
||||||
> - In this particular example of type class, the type `m` must be a type that take an argument.
|
> - In this particular example of type class, the type `m` must be a type that takes an argument.
|
||||||
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
||||||
> - To be a useful monad, your function must obey some rule.
|
> - To be a useful monad, your function must obey some rules.
|
||||||
> If your construction does not obey these rules strange things might happens:
|
> If your construction does not obey these rules strange things might happens:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -2970,13 +2971,13 @@ class Monad m where
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
There exists a lot of different type that are instance of `Monad`.
|
There are a lot of different types that are instance of `Monad`.
|
||||||
One of the easiest to describe is `Maybe`.
|
One of the easiest to describe is `Maybe`.
|
||||||
If you have a sequence of `Maybe` values, you could use monad to manipulate them.
|
If you have a sequence of `Maybe` values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep `if..then..else..` constructions.
|
It is particularly useful to remove very deep `if..then..else..` constructions.
|
||||||
|
|
||||||
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.
|
if you can afford to follow a list of operations without being negative.
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3016,7 +3017,7 @@ main = do
|
||||||
|
|
||||||
<hr/><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a>
|
<hr/><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a>
|
||||||
|
|
||||||
Now, let's make it better using Maybe and the fact it is a Monad
|
Now, let's make it better using Maybe and the fact that it is a Monad
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3072,7 +3073,7 @@ main = do
|
||||||
print $ eligible 299 -- Nothing
|
print $ eligible 299 -- Nothing
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
We have proved Monad are nice to make our code more elegant.
|
We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for `Maybe` can be used
|
Note this idea of code organization, in particular for `Maybe` can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.
|
In fact, this is the kind of construction we make naturally.
|
||||||
|
@ -3081,7 +3082,7 @@ In fact, this is the kind of construction we make naturally.
|
||||||
>
|
>
|
||||||
> The first element in the sequence being evaluated to `Nothing` will stop
|
> The first element in the sequence being evaluated to `Nothing` will stop
|
||||||
> the complete evaluation.
|
> the complete evaluation.
|
||||||
> That means, you don't execute all lines.
|
> This means you don't execute all lines.
|
||||||
> You have this for free, thanks to laziness.
|
> You have this for free, thanks to laziness.
|
||||||
|
|
||||||
The `Maybe` monad proved to be useful while being a very simple example.
|
The `Maybe` monad proved to be useful while being a very simple example.
|
||||||
|
@ -3096,7 +3097,7 @@ But now a cooler example, lists.
|
||||||
|
|
||||||
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
||||||
|
|
||||||
The list monad help us to simulate non deterministic computation.
|
The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:
|
Here we go:
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -3133,8 +3134,8 @@ For the list monad, there is also a syntactical sugar:
|
||||||
4*x + 2*y < z ]
|
4*x + 2*y < z ]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
I won't list all the monads, but there is a lot of monads.
|
I won't list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for:
|
In particular, monad are very useful for:
|
||||||
|
|
||||||
- IO,
|
- IO,
|
||||||
|
@ -3147,7 +3148,9 @@ In particular, monad are very useful for:
|
||||||
If you have followed me until here, then you've done it!
|
If you have followed me until here, then you've done it!
|
||||||
You know monads[^03021301]!
|
You know monads[^03021301]!
|
||||||
|
|
||||||
[^03021301]: Well, you'll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.
|
[^03021301]: Well, you'll certainly need to practice a bit to get used to them
|
||||||
|
and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.
|
||||||
|
|
||||||
<a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a>
|
<a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a>
|
||||||
|
|
||||||
|
@ -3160,14 +3163,15 @@ It is just here to discuss some details further.
|
||||||
|
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
In the section [Infinite Structures](#infinite-structures) we saw some simple construction.
|
In the section [Infinite Structures](#infinite-structures) we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:
|
||||||
|
|
||||||
1. no duplicate node value
|
1. no duplicate node value
|
||||||
2. well ordered tree
|
2. well ordered tree
|
||||||
|
|
||||||
In this section we will try to keep the first property.
|
In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we'll discuss on how to
|
Concerning the second one, we must relax it but we'll discuss how to
|
||||||
keep it as much as possible.
|
keep it as much as possible.
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -3230,7 +3234,7 @@ Our first step is to create some pseudo-random number list:
|
||||||
shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
||||||
</code>
|
</code>
|
||||||
</div>
|
</div>
|
||||||
Just as reminder here are the definition of `treeFromList`
|
Just as a reminder, here is the definition of `treeFromList`
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -3297,16 +3301,16 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
will loop forever.
|
will loop forever.
|
||||||
Simply because, it will try to access the head of `filter (<1) [2..]`.
|
Simply because it will try to access the head of `filter (<1) [2..]`.
|
||||||
But filter is not smart enought to understand that the result is the empty list.
|
But `filter` is not smart enought to understand that the result is the empty list.
|
||||||
|
|
||||||
Nonetheless, it is still a very cool example of what non strict program has to offer.
|
Nonetheless, it is still a very cool example of what non strict programs have to offer.
|
||||||
|
|
||||||
Left as an exercise to the reader:
|
Left as an exercise to the reader:
|
||||||
|
|
||||||
- Could you prove that there exists some number `n` such that `treeTakeDepth n (treeFromList shuffle)` will enter in an infinite loop.
|
- Prove the existence of a number `n` so that `treeTakeDepth n (treeFromList shuffle)` will enter an infinite loop.
|
||||||
- Find an upper bound for `n`.
|
- Find an upper bound for `n`.
|
||||||
- Prove there is no `shuffle` list such that, for any depth, the program ends.
|
- Prove there is no `shuffle` list so that, for any depth, the program ends.
|
||||||
|
|
||||||
<a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a>
|
<a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a>
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
Congratulation to get so far!
|
Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.
|
Now, some of the really hardcore stuff can start.
|
||||||
|
|
||||||
If you are like me, you should get the functional style.
|
If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don't really understand were to start to make a real program.
|
But you also don't really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:
|
And in particular:
|
||||||
|
|
||||||
- How do you deal with effects?
|
- How do you deal with effects?
|
||||||
- Why is there a strange imperative-like notation for dealing with IO?
|
- Why is there a strange imperative-like notation for dealing with IO?
|
||||||
|
|
||||||
Be prepared, answer might be difficult to get.
|
Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.
|
But they all be very rewarding.
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
> <%=tldr%>
|
> <%=tldr%>
|
||||||
>
|
>
|
||||||
> A typical function doing `IO` look a lot like an imperative language:
|
> A typical function doing `IO` looks a lot like an imperative program:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> f :: IO a
|
> f :: IO a
|
||||||
|
@ -23,15 +23,15 @@
|
||||||
> - `action3 :: IO c`
|
> - `action3 :: IO c`
|
||||||
> - `action4 x y :: IO a`
|
> - `action4 x y :: IO a`
|
||||||
> - `x :: b`, `y :: c`
|
> - `x :: b`, `y :: c`
|
||||||
> - Few objects have the type `IO a`, this should help you to choose.
|
> - Few objects have the type `IO a`, this should help you choose.
|
||||||
> In particular you cannot use pure function directly here.
|
> In particular you cannot use pure functions directly here.
|
||||||
> To use pure function you could do `action2 (purefunction x)` for example.
|
> To use pure functions you could do `action2 (purefunction x)` for example.
|
||||||
|
|
||||||
In this section, I will explain how to use IO, not how they work.
|
In this section, I will explain how to use IO, not how it works.
|
||||||
You'll see how Haskell separate pure from impure part of the program.
|
You'll see how Haskell separates the pure from the impure parts of the program.
|
||||||
|
|
||||||
Don't stop because you're trying to understand the details of the syntax.
|
Don't stop because you're trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.
|
Answers will come in the next section.
|
||||||
|
|
||||||
What to achieve?
|
What to achieve?
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Or more interestingly, we remark each expression in the `do` block has a type of `IO a`.
|
Or more interestingly, we note that each expression in the `do` block has a type of `IO a`.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -64,7 +64,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
We should also remark the effect of the `<-` symbol.
|
We should also pay attention to the effect of the `<-` symbol.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
do
|
do
|
||||||
|
@ -73,8 +73,8 @@ do
|
||||||
|
|
||||||
If `something :: IO a` then `x :: a`.
|
If `something :: IO a` then `x :: a`.
|
||||||
|
|
||||||
Another important remark to use `IO`.
|
Another important note about using `IO`.
|
||||||
All line in a do block must have one of the two forms:
|
All lines in a do block must be of one of the two forms:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
action1 :: IO a
|
action1 :: IO a
|
||||||
|
@ -89,5 +89,5 @@ value <- action2 -- where
|
||||||
-- value :: b
|
-- value :: b
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
These two kind of line will correspond to two different way of sequencing actions.
|
These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.
|
The meaning of this sentence should be clearer by the end of the next section.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Now let's see how this behave.
|
Now let's see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let's try:
|
Let's try:
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ Let's try:
|
||||||
Argh! An evil error message and a crash!
|
Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.
|
The first evolution will be to answer with a more friendly message.
|
||||||
|
|
||||||
For this, we must detect, something went wrong.
|
In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type `Maybe`.
|
Use the type `Maybe`.
|
||||||
It is a very common type in Haskell.
|
It is a very common type in Haskell.
|
||||||
|
|
||||||
> import Data.Maybe
|
> import Data.Maybe
|
||||||
|
|
||||||
What is this thing? Maybe is a type which takes one parameter.
|
What is this thing? `Maybe` is a type which takes one parameter.
|
||||||
Its definition is:
|
Its definition is:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -61,23 +61,24 @@ We simply have to test the value in our main function.
|
||||||
> Just l -> print (sum l)
|
> Just l -> print (sum l)
|
||||||
> Nothing -> error "Bad format. Good Bye."
|
> Nothing -> error "Bad format. Good Bye."
|
||||||
|
|
||||||
In case of error, we prompt a nice error message.
|
In case of error, we display a nice error message.
|
||||||
|
|
||||||
Remark the type of each expression in the main's do block remains of the form `IO a`.
|
Note that the type of each expression in the main's do block remains of the form `IO a`.
|
||||||
The only strange construction is `error`.
|
The only strange construction is `error`.
|
||||||
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
||||||
|
|
||||||
One very important thing to note is the type of all the defined function.
|
One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains `IO` in its type: `main`.
|
There is only one function which contains `IO` in its type: `main`.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use `getListFromString` which is pure.
|
But main uses `getListFromString` which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.
|
||||||
|
|
||||||
Why purity matters?
|
Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:
|
I certainly forget many advantages, but the three main reasons are:
|
||||||
|
|
||||||
- It is far easier to think about pure code than impure one.
|
- It is far easier to think about pure code than impure one.
|
||||||
- Purity protect you from all hard to reproduce bugs due to border effects.
|
- Purity protects you from all the hard to reproduce bugs due to side effects.
|
||||||
- You can evaluate pure functions in any order or in parallel without risk.
|
- You can evaluate pure functions in any order or in parallel without risk.
|
||||||
|
|
||||||
This is why, you should generally put as most code as possible in pure functions.
|
This is why you should generally put as most code as possible inside pure functions.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Our next evolution will be to ask the user again and again until it enters a valid answer.
|
Our next evolution will be to prompt the user again and again until she enters a valid answer.
|
||||||
|
|
||||||
We keep the first part:
|
We keep the first part:
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ We keep the first part:
|
||||||
> getListFromString :: String -> Maybe [Integer]
|
> getListFromString :: String -> Maybe [Integer]
|
||||||
> getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
> getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
||||||
|
|
||||||
Now, we create a function which will ask the user for an integer list
|
Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.
|
until the input is right.
|
||||||
|
|
||||||
> askUser :: IO [Integer]
|
> askUser :: IO [Integer]
|
||||||
|
@ -24,14 +24,14 @@ until the input is right.
|
||||||
> Nothing -> askUser
|
> Nothing -> askUser
|
||||||
|
|
||||||
This function is of type `IO [Integer]`.
|
This function is of type `IO [Integer]`.
|
||||||
Such a type means, that we retrieved a value of type `[Integer]` through some IO actions.
|
Such a type means that we retrieved a value of type `[Integer]` through some IO actions.
|
||||||
Some people might explain while waving their hands:
|
Some people might explain while waving their hands:
|
||||||
|
|
||||||
> «This is an `[Integer]` inside an `IO`»
|
> «This is an `[Integer]` inside an `IO`»
|
||||||
|
|
||||||
If you want to understand the details behind all of this, you'll have to read the next section.
|
If you want to understand the details behind all of this, you'll have to read the next section.
|
||||||
But sincerely, if you just want to _use_ IO.
|
But sincerely, if you just want to _use_ IO.
|
||||||
Just exercise a little and remember to think about the type.
|
Just practice a little and remember to think about the type.
|
||||||
|
|
||||||
Finally our main function is quite simpler:
|
Finally our main function is quite simpler:
|
||||||
|
|
||||||
|
@ -41,18 +41,18 @@ Finally our main function is quite simpler:
|
||||||
> print $ sum list
|
> print $ sum list
|
||||||
|
|
||||||
We have finished with our introduction to `IO`.
|
We have finished with our introduction to `IO`.
|
||||||
This was quite a fast. Here are the main things to remind:
|
This was quite fast. Here are the main things to remember:
|
||||||
|
|
||||||
- in the `do` bloc, each expression must have the type `IO a`.
|
- in the `do` bloc, each expression must have the type `IO a`.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, `getLine`, `print`, `putStrLn`, etc...
|
For example, `getLine`, `print`, `putStrLn`, etc...
|
||||||
- Try to externalize the pure function as much as possible.
|
- Try to externalize the pure functions as much as possible.
|
||||||
- the `IO a` type means: an IO _action_ which return an element of type `a`.
|
- the `IO a` type means: an IO _action_ which returns an element of type `a`.
|
||||||
`IO` represent action; under the hood, `IO a` is the type of a function.
|
`IO` represents actions; under the hood, `IO a` is the type of a function.
|
||||||
Read the next section if you are curious.
|
Read the next section if you are curious.
|
||||||
|
|
||||||
If you exercise a bit, you should be able to _use_ `IO`.
|
If you practice a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> _Exercises_:
|
> _Exercises_:
|
||||||
>
|
>
|
||||||
> - Make a program that sum all its argument. Hint: use the function `getArgs`.
|
> - Make a program that sums all of its arguments. Hint: use the function `getArgs`.
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
> Here is a <%=tldr%> for this section.
|
> Here is a <%=tldr%> for this section.
|
||||||
>
|
>
|
||||||
> To separate pure from impure part,
|
> To separate pure and impure parts,
|
||||||
> the main is defined as a function
|
> `main` is defined as a function
|
||||||
> which modify the state of the world
|
> which modifies the state of the world
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main :: World -> World
|
> main :: World -> World
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> A function is granted to have side effect only if it gets this value.
|
> A function is guaranteed to have side effects only if it has this type.
|
||||||
> But look at a typical main function:
|
> But look at a typical main function:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -24,17 +24,17 @@
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
||||||
> which must be passed to the next action.
|
> which must be passed on to the next action.
|
||||||
>
|
>
|
||||||
> We create a function `bind` or `(>>=)`.
|
> We create a function `bind` or `(>>=)`.
|
||||||
> With `bind` we need no more temporary name.
|
> With `bind` we don't need temporary names anymore.
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main =
|
> main =
|
||||||
> action1 >>= action2 >>= action3 >>= action4
|
> action1 >>= action2 >>= action3 >>= action4
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> Bonus: Haskell has a syntactical sugar for us:
|
> Bonus: Haskell has syntactical sugar for us:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main = do
|
> main = do
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
> ~~~
|
> ~~~
|
||||||
|
|
||||||
|
|
||||||
Why did we used some strange syntax, and what exactly is this `IO` type.
|
Why did we use this strange syntax, and what exactly is this `IO` type?
|
||||||
It looks a bit like magic.
|
It looks a bit like magic.
|
||||||
|
|
||||||
For now let's just forget about all the pure part of our program, and focus
|
For now let's just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:
|
on the impure parts:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: IO [Integer]
|
askUser :: IO [Integer]
|
||||||
|
@ -68,33 +68,33 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First remark; it looks like an imperative structure.
|
First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a `while` in Haskell.
|
For example, if you wish you could create a `while` in Haskell.
|
||||||
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
||||||
|
|
||||||
But, you should had remarked the notation is a bit unusual.
|
But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.
|
Here is why, in detail.
|
||||||
|
|
||||||
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.
|
The fact that a file exists or not can be seen as different states of the world.
|
||||||
|
|
||||||
For Haskell this state is not hidden.
|
For Haskell this state is not hidden.
|
||||||
It is explicitly said `main` is a function that _potentially_ change the state of the world.
|
It is explicitly said `main` is a function that _potentially_ changes the state of the world.
|
||||||
It's type is then something like:
|
Its type is then something like:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
main :: World -> World
|
main :: World -> World
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not all function could have access to this variable.
|
Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn't provided to should be pure[^032001].
|
Functions to which the world variable isn't provided are pure[^032001].
|
||||||
|
|
||||||
[^032001]: There are some _unsafe_ exception to this rule. But you shouldn't see such usage on a real application except might be for some debugging purpose.
|
[^032001]: There are some _unsafe_ exceptions to this rule. But you shouldn't see such use on a real application except maybe for debugging purpose.
|
||||||
|
|
||||||
Haskell consider the state of the world is an input variable for `main`.
|
Haskell considers the state of the world as an input variable to `main`.
|
||||||
But the real type of main is closer to this one[^032002]:
|
But the real type of main is closer to this one[^032002]:
|
||||||
|
|
||||||
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
||||||
|
@ -115,17 +115,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First, we remark, that all function which have side effect must have the type:
|
First, we note that all functions which have side effects must have the type:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
World -> (a,World)
|
World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Where `a` is the type of result.
|
Where `a` is the type of the result.
|
||||||
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
||||||
|
|
||||||
Another thing to remark is the trick to fix the order of evaluation.
|
Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate `f a b`, you generally have many choices:
|
In Haskell, in order to evaluate `f a b`, you have many choices:
|
||||||
|
|
||||||
- first eval `a` then `b` then `f a b`
|
- first eval `a` then `b` then `f a b`
|
||||||
- first eval `b` then `a` then `f a b`.
|
- first eval `b` then `a` then `f a b`.
|
||||||
|
@ -146,7 +146,7 @@ Under the hood, `print` will evaluate as:
|
||||||
- evaluate as `((),new world id)`.
|
- evaluate as `((),new world id)`.
|
||||||
|
|
||||||
Now, if you look at the style of the main function, it is clearly awkward.
|
Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let's try to make the same to the askUser function:
|
Let's try to do the same to the askUser function:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: World -> ([Integer],World)
|
askUser :: World -> ([Integer],World)
|
||||||
|
@ -181,9 +181,9 @@ askUser w0 =
|
||||||
This is similar, but awkward.
|
This is similar, but awkward.
|
||||||
Look at all these temporary `w?` names.
|
Look at all these temporary `w?` names.
|
||||||
|
|
||||||
The lesson, is, naive IO implementation in Pure functional language is awkward!
|
The lesson, is, naive IO implementation in Pure functional languages is awkward!
|
||||||
|
|
||||||
Fortunately, some have found a better way to handle this problem.
|
Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:
|
Each line is of the form:
|
||||||
|
|
||||||
|
@ -199,8 +199,7 @@ Each function `f` must have a type similar to:
|
||||||
f :: World -> (a,World)
|
f :: World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not only this, but we can also remark we use them always
|
Not only this, but we can also note that we always follow the same usage pattern:
|
||||||
with the following general pattern:
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (y,w1) = action1 w0 in
|
let (y,w1) = action1 w0 in
|
||||||
|
@ -209,7 +208,7 @@ let (t,w3) = action3 w2 in
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Each action can take 0 to some parameters.
|
Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.
|
And in particular, each action can take a parameter from the result of a line above.
|
||||||
|
|
||||||
For example, we could also have:
|
For example, we could also have:
|
||||||
|
@ -223,7 +222,7 @@ let (_,w3) = action3 x z w2 in
|
||||||
|
|
||||||
And of course `actionN w :: (World) -> (a,World)`.
|
And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
> IMPORTANT, there are only two important pattern for us:
|
> IMPORTANT, there are only two important patterns to consider:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> let (x,w1) = action1 w0 in
|
> let (x,w1) = action1 w0 in
|
||||||
|
@ -239,7 +238,7 @@ And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
||||||
|
|
||||||
Now, we will make a magic trick.
|
Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol "disappear".
|
We will make the temporary world symbol "disappear".
|
||||||
We will `bind` the two lines.
|
We will `bind` the two lines.
|
||||||
Let's define the `bind` function.
|
Let's define the `bind` function.
|
||||||
|
@ -265,18 +264,18 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
`getLine` is an IO action which take a world as parameter and return a couple `(String,World)`.
|
`getLine` is an IO action which takes a world as parameter and returns a couple `(String,World)`.
|
||||||
Which can be said as: `getLine` is of type `IO String`.
|
Which can be summarized as: `getLine` is of type `IO String`.
|
||||||
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
||||||
|
|
||||||
The function `print` is also interresting.
|
The function `print` is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type `((),World)`.
|
It then returns a couple of type `((),World)`.
|
||||||
This means it changes the world state, but don't give anymore data.
|
This means it changes the state of the world, but doesn't yield anymore data.
|
||||||
|
|
||||||
This type help us simplify the type of `bind`:
|
This type helps us simplify the type of `bind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
bind :: IO a
|
bind :: IO a
|
||||||
|
@ -302,7 +301,7 @@ action2 :: a -> IO b
|
||||||
(y,w2) :: IO b
|
(y,w2) :: IO b
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Doesn't seem familiar?
|
Doesn't it seem familiar?
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -312,7 +311,7 @@ Doesn't seem familiar?
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
The idea is to hide the World argument with this function. Let's go:
|
The idea is to hide the World argument with this function. Let's go:
|
||||||
As example imagine if we wanted to simulate:
|
As an example imagine if we wanted to simulate:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -327,7 +326,7 @@ Now, using the bind function:
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
As print is of type (World -> ((),World)), we know res = () (null type).
|
As print is of type (World -> ((),World)), we know res = () (null type).
|
||||||
If you didn't saw what was magic here, let's try with three lines this time.
|
If you didn't see what was magic here, let's try with three lines this time.
|
||||||
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -345,8 +344,8 @@ Which is equivalent to:
|
||||||
print (line1 ++ line2)))
|
print (line1 ++ line2)))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Didn't you remark something?
|
Didn't you notice something?
|
||||||
Yes, there isn't anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is _MA_. _GIC_.
|
This is _MA_. _GIC_.
|
||||||
|
|
||||||
We can use a better notation.
|
We can use a better notation.
|
||||||
|
@ -361,7 +360,7 @@ Let's use `(>>=)` instead of `bind`.
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Ho Ho Ho! Happy Christmas Everyone!
|
Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:
|
Haskell has made syntactical sugar for us:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
do
|
do
|
||||||
|
@ -382,8 +381,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
||||||
|
|
||||||
But what for line not using the `<-`?
|
But what about the lines not using the `<-`?
|
||||||
Easy another function `blindBind`:
|
Easy, another function `blindBind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
blindBind :: IO a -> IO b -> IO b
|
blindBind :: IO a -> IO b -> IO b
|
||||||
|
@ -391,7 +390,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
I didn't simplified this definition for clarity purpose.
|
I didn't simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we'll use the `(>>)` operator.
|
Of course we can use a better notation, we'll use the `(>>)` operator.
|
||||||
|
|
||||||
And
|
And
|
||||||
|
@ -418,7 +417,6 @@ putInIO :: a -> IO a
|
||||||
putInIO x = IO (\w -> (x,w))
|
putInIO x = IO (\w -> (x,w))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
This is the general way to put pure value inside the "IO context".
|
This is the general way to put pure values inside the "IO context".
|
||||||
The general name for `putInIO` is `return`.
|
The general name for `putInIO` is `return`.
|
||||||
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,6 @@ Is translated into:
|
||||||
> main = askUser >>=
|
> main = askUser >>=
|
||||||
> \list -> print $ sum list
|
> \list -> print $ sum list
|
||||||
|
|
||||||
You can compile this code to verify it continues to work.
|
You can compile this code to verify it keeps working.
|
||||||
|
|
||||||
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
|
@ -2,13 +2,13 @@ First, let's take a look at the IO type.
|
||||||
|
|
||||||
> newtype IO a = IO (State# RealWorld -> (# State# RealWorld,a #))
|
> newtype IO a = IO (State# RealWorld -> (# State# RealWorld,a #))
|
||||||
|
|
||||||
Ho gosh! What is this notation?
|
Oh gosh! What is this notation?
|
||||||
|
|
||||||
I said it will be Haskell the hard way. It is.
|
I said it will be Haskell the hard way. It is.
|
||||||
Now make it easier.
|
Now make it easier.
|
||||||
|
|
||||||
First, we need to understand basic concepts.
|
First, we need to understand some basic concepts.
|
||||||
You can just forget about all these sharp sybols.
|
You can just forget about all these sharp symbols.
|
||||||
|
|
||||||
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ RealWorld is deeply magical.
|
||||||
It is primitive, but it is not unlifted (hence ptrArg).
|
It is primitive, but it is not unlifted (hence ptrArg).
|
||||||
We never manipulate values of type RealWorld; it's only used in the type system, to parameterise `State#`.
|
We never manipulate values of type RealWorld; it's only used in the type system, to parameterise `State#`.
|
||||||
|
|
||||||
Hu? It is a type with nothing inside it.
|
Uh? It is a type with nothing inside it.
|
||||||
No representation for it at all.
|
No representation for it at all.
|
||||||
It is just a name.
|
It is just a name.
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ It is a data with one parameter, a type of state.
|
||||||
|
|
||||||
The only purpose of the type parameter (`s`) is to keep different state threads separate.
|
The only purpose of the type parameter (`s`) is to keep different state threads separate.
|
||||||
|
|
||||||
In fact, let's try to traduce
|
In fact, let's try to translate
|
||||||
|
|
||||||
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
||||||
|
|
||||||
|
@ -46,21 +46,21 @@ of type (State RealWorld, String).
|
||||||
|
|
||||||
Which if we simplify another time can be said as:
|
Which if we simplify another time can be said as:
|
||||||
|
|
||||||
IO String is a function for a state of the world to anotherstate of the world and an String value.
|
IO String is a function which turns one state of the world into another state of the world and an String value.
|
||||||
|
|
||||||
It seems it fit nicely a function like `getLine`.
|
It seems to fit nicely with a function like `getLine`.
|
||||||
|
|
||||||
getLine can be functino in which we provide a state of the real world.
|
`getLine` can be a function to which we provide a state of the real world.
|
||||||
Then getLine do his job, then after that, it provide us a couple.
|
Then `getLine` does its job, then after this, it provides us with a couple of
|
||||||
|
values.
|
||||||
The String containing the content of the line read, and the changed world state.
|
The String containing the content of the line read, and the changed world state.
|
||||||
Changed because, when we had read something, the state of the world changed.
|
Changed because, when we had read something, the state of the world changed.
|
||||||
|
|
||||||
Congratulation to have followed the first _Hardcore Haskell IO_ level 1.
|
Congratulations for having followed the first _Hardcore Haskell IO_ level 1.
|
||||||
|
|
||||||
Now, it will be time to go to level 2.
|
Now, it is time to go to level 2.
|
||||||
|
|
||||||
To make things clearer, I will augment the verbosity of the type. And instead of writting `IO a`. I will write `World -> (World,a)`.
|
To make things clearer, I will increase the verbosity of the type. And instead of writing `IO a`. I will write `World -> (World,a)`.
|
||||||
|
|
||||||
It was a nice help for me.
|
It was a nice help for me.
|
||||||
It is often hard to remember that "IO a" is in fact a function.
|
It is often hard to remember that "IO a" is in fact a function.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<%= blogimage("dali_reve.jpg","Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
<%= blogimage("dali_reve.jpg","Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
||||||
|
|
||||||
Now the secret can be revealed: `IO` is a _monad_.
|
Now the secret can be revealed: `IO` is a _monad_.
|
||||||
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.
|
But mainly, you have access to a coding pattern which will ease the flow of your code.
|
||||||
|
|
||||||
> **Important remarks**:
|
> **Important remarks**:
|
||||||
>
|
>
|
||||||
|
@ -36,13 +36,13 @@ class Monad m where
|
||||||
>
|
>
|
||||||
> - the keyword `class` is not your friend.
|
> - the keyword `class` is not your friend.
|
||||||
> A Haskell class is _not_ a class like in object model.
|
> A Haskell class is _not_ a class like in object model.
|
||||||
> A Haskell class has a lot similarities with Java interfaces.
|
> A Haskell class has a lot of similarities with Java interfaces.
|
||||||
> A better word should have been `typeclass`.
|
> A better word should have been `typeclass`.
|
||||||
> That means a set of types.
|
> That means a set of types.
|
||||||
> For a type to belong to a class, all function of the class must be provided for this type.
|
> For a type to belong to a class, all functions of the class must be provided for this type.
|
||||||
> - In this particular example of type class, the type `m` must be a type that take an argument.
|
> - In this particular example of type class, the type `m` must be a type that takes an argument.
|
||||||
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
||||||
> - To be a useful monad, your function must obey some rule.
|
> - To be a useful monad, your function must obey some rules.
|
||||||
> If your construction does not obey these rules strange things might happens:
|
> If your construction does not obey these rules strange things might happens:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -53,13 +53,13 @@ class Monad m where
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
There exists a lot of different type that are instance of `Monad`.
|
There are a lot of different types that are instance of `Monad`.
|
||||||
One of the easiest to describe is `Maybe`.
|
One of the easiest to describe is `Maybe`.
|
||||||
If you have a sequence of `Maybe` values, you could use monad to manipulate them.
|
If you have a sequence of `Maybe` values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep `if..then..else..` constructions.
|
It is particularly useful to remove very deep `if..then..else..` constructions.
|
||||||
|
|
||||||
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.
|
if you can afford to follow a list of operations without being negative.
|
||||||
|
|
||||||
> deposit value account = account + value
|
> deposit value account = account + value
|
||||||
> withdraw value account = account - value
|
> withdraw value account = account - value
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Now, let's make it better using Maybe and the fact it is a Monad
|
Now, let's make it better using Maybe and the fact that it is a Monad
|
||||||
|
|
||||||
> deposit :: (Num a) => a -> a -> Maybe a
|
> deposit :: (Num a) => a -> a -> Maybe a
|
||||||
> deposit value account = Just (account + value)
|
> deposit value account = Just (account + value)
|
||||||
|
|
|
@ -21,7 +21,7 @@ Not bad, but we can make it even better:
|
||||||
> print $ eligible 300 -- Just True
|
> print $ eligible 300 -- Just True
|
||||||
> print $ eligible 299 -- Nothing
|
> print $ eligible 299 -- Nothing
|
||||||
|
|
||||||
We have proved Monad are nice to make our code more elegant.
|
We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for `Maybe` can be used
|
Note this idea of code organization, in particular for `Maybe` can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.
|
In fact, this is the kind of construction we make naturally.
|
||||||
|
@ -30,7 +30,7 @@ In fact, this is the kind of construction we make naturally.
|
||||||
>
|
>
|
||||||
> The first element in the sequence being evaluated to `Nothing` will stop
|
> The first element in the sequence being evaluated to `Nothing` will stop
|
||||||
> the complete evaluation.
|
> the complete evaluation.
|
||||||
> That means, you don't execute all lines.
|
> This means you don't execute all lines.
|
||||||
> You have this for free, thanks to laziness.
|
> You have this for free, thanks to laziness.
|
||||||
|
|
||||||
The `Maybe` monad proved to be useful while being a very simple example.
|
The `Maybe` monad proved to be useful while being a very simple example.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
||||||
|
|
||||||
The list monad help us to simulate non deterministic computation.
|
The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:
|
Here we go:
|
||||||
|
|
||||||
> import Control.Monad (guard)
|
> import Control.Monad (guard)
|
||||||
|
@ -34,8 +34,8 @@ For the list monad, there is also a syntactical sugar:
|
||||||
> z <- allCases,
|
> z <- allCases,
|
||||||
> 4*x + 2*y < z ]
|
> 4*x + 2*y < z ]
|
||||||
|
|
||||||
I won't list all the monads, but there is a lot of monads.
|
I won't list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for:
|
In particular, monad are very useful for:
|
||||||
|
|
||||||
- IO,
|
- IO,
|
||||||
|
@ -48,4 +48,6 @@ In particular, monad are very useful for:
|
||||||
If you have followed me until here, then you've done it!
|
If you have followed me until here, then you've done it!
|
||||||
You know monads[^03021301]!
|
You know monads[^03021301]!
|
||||||
|
|
||||||
[^03021301]: Well, you'll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.
|
[^03021301]: Well, you'll certainly need to practice a bit to get used to them
|
||||||
|
and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
In the section [Infinite Structures](#infinite-structures) we saw some simple construction.
|
In the section [Infinite Structures](#infinite-structures) we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:
|
||||||
|
|
||||||
1. no duplicate node value
|
1. no duplicate node value
|
||||||
2. well ordered tree
|
2. well ordered tree
|
||||||
|
|
||||||
In this section we will try to keep the first property.
|
In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we'll discuss on how to
|
Concerning the second one, we must relax it but we'll discuss how to
|
||||||
keep it as much as possible.
|
keep it as much as possible.
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -64,7 +65,7 @@ Our first step is to create some pseudo-random number list:
|
||||||
|
|
||||||
> shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
> shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
||||||
|
|
||||||
Just as reminder here are the definition of `treeFromList`
|
Just as a reminder, here is the definition of `treeFromList`
|
||||||
|
|
||||||
> treeFromList :: (Ord a) => [a] -> BinTree a
|
> treeFromList :: (Ord a) => [a] -> BinTree a
|
||||||
> treeFromList [] = Empty
|
> treeFromList [] = Empty
|
||||||
|
@ -122,13 +123,13 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
will loop forever.
|
will loop forever.
|
||||||
Simply because, it will try to access the head of `filter (<1) [2..]`.
|
Simply because it will try to access the head of `filter (<1) [2..]`.
|
||||||
But filter is not smart enought to understand that the result is the empty list.
|
But `filter` is not smart enought to understand that the result is the empty list.
|
||||||
|
|
||||||
Nonetheless, it is still a very cool example of what non strict program has to offer.
|
Nonetheless, it is still a very cool example of what non strict programs have to offer.
|
||||||
|
|
||||||
Left as an exercise to the reader:
|
Left as an exercise to the reader:
|
||||||
|
|
||||||
- Could you prove that there exists some number `n` such that `treeTakeDepth n (treeFromList shuffle)` will enter in an infinite loop.
|
- Prove the existence of a number `n` so that `treeTakeDepth n (treeFromList shuffle)` will enter an infinite loop.
|
||||||
- Find an upper bound for `n`.
|
- Find an upper bound for `n`.
|
||||||
- Prove there is no `shuffle` list such that, for any depth, the program ends.
|
- Prove there is no `shuffle` list so that, for any depth, the program ends.
|
||||||
|
|
|
@ -2236,12 +2236,13 @@ main = <span class="Keyword">do</span>
|
||||||
|
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
<p>Congratulation to get so far!
|
<p>Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.</p>
|
Now, some of the really hardcore stuff can start.</p>
|
||||||
|
|
||||||
<p>If you are like me, you should get the functional style.
|
<p>If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don’t really understand were to start to make a real program.
|
But you also don’t really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:</p>
|
And in particular:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -2249,7 +2250,7 @@ And in particular:</p>
|
||||||
<li>Why is there a strange imperative-like notation for dealing with IO?</li>
|
<li>Why is there a strange imperative-like notation for dealing with IO?</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Be prepared, answer might be difficult to get.
|
<p>Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.</p>
|
But they all be very rewarding.</p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -2262,7 +2263,7 @@ But they all be very rewarding.</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span></p>
|
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span></p>
|
||||||
|
|
||||||
<p>A typical function doing <code>IO</code> look a lot like an imperative language:</p>
|
<p>A typical function doing <code>IO</code> looks a lot like an imperative program:</p>
|
||||||
|
|
||||||
<pre><code>f :: IO a
|
<pre><code>f :: IO a
|
||||||
f = do
|
f = do
|
||||||
|
@ -2284,17 +2285,17 @@ in this example:
|
||||||
<li><code>x :: b</code>, <code>y :: c</code></li>
|
<li><code>x :: b</code>, <code>y :: c</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Few objects have the type <code>IO a</code>, this should help you to choose.
|
<li>Few objects have the type <code>IO a</code>, this should help you choose.
|
||||||
In particular you cannot use pure function directly here.
|
In particular you cannot use pure functions directly here.
|
||||||
To use pure function you could do <code>action2 (purefunction x)</code> for example.</li>
|
To use pure functions you could do <code>action2 (purefunction x)</code> for example.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>In this section, I will explain how to use IO, not how they work.
|
<p>In this section, I will explain how to use IO, not how it works.
|
||||||
You’ll see how Haskell separate pure from impure part of the program.</p>
|
You’ll see how Haskell separates the pure from the impure parts of the program.</p>
|
||||||
|
|
||||||
<p>Don’t stop because you’re trying to understand the details of the syntax.
|
<p>Don’t stop because you’re trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.</p>
|
Answers will come in the next section.</p>
|
||||||
|
|
||||||
<p>What to achieve?</p>
|
<p>What to achieve?</p>
|
||||||
|
|
||||||
|
@ -2322,7 +2323,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Or more interestingly, we remark each expression in the <code>do</code> block has a type of <code>IO a</code>.</p>
|
<p>Or more interestingly, we note that each expression in the <code>do</code> block has a type of <code>IO a</code>.</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -2331,7 +2332,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>We should also remark the effect of the <code><-</code> symbol.</p>
|
<p>We should also pay attention to the effect of the <code><-</code> symbol.</p>
|
||||||
|
|
||||||
<pre><code>do
|
<pre><code>do
|
||||||
x <- something
|
x <- something
|
||||||
|
@ -2339,8 +2340,8 @@ main = do
|
||||||
|
|
||||||
<p>If <code>something :: IO a</code> then <code>x :: a</code>.</p>
|
<p>If <code>something :: IO a</code> then <code>x :: a</code>.</p>
|
||||||
|
|
||||||
<p>Another important remark to use <code>IO</code>.
|
<p>Another important note about using <code>IO</code>.
|
||||||
All line in a do block must have one of the two forms:</p>
|
All lines in a do block must be of one of the two forms:</p>
|
||||||
|
|
||||||
<pre><code>action1 :: IO a
|
<pre><code>action1 :: IO a
|
||||||
-- in this case, generally a = ()
|
-- in this case, generally a = ()
|
||||||
|
@ -2353,15 +2354,15 @@ All line in a do block must have one of the two forms:</p>
|
||||||
-- value :: b
|
-- value :: b
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>These two kind of line will correspond to two different way of sequencing actions.
|
<p>These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.</p>
|
The meaning of this sentence should be clearer by the end of the next section.</p>
|
||||||
|
|
||||||
<p><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a></p>
|
<p><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a></p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a></p>
|
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a></p>
|
||||||
|
|
||||||
<p>Now let’s see how this behave.
|
<p>Now let’s see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let’s try:</p>
|
Let’s try:</p>
|
||||||
|
|
||||||
|
@ -2374,7 +2375,7 @@ Let’s try:</p>
|
||||||
<p>Argh! An evil error message and a crash!
|
<p>Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.</p>
|
The first evolution will be to answer with a more friendly message.</p>
|
||||||
|
|
||||||
<p>For this, we must detect, something went wrong.
|
<p>In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type <code>Maybe</code>.
|
Use the type <code>Maybe</code>.
|
||||||
It is a very common type in Haskell.</p>
|
It is a very common type in Haskell.</p>
|
||||||
|
@ -2384,7 +2385,7 @@ It is a very common type in Haskell.</p>
|
||||||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>What is this thing? Maybe is a type which takes one parameter.
|
<p>What is this thing? <code>Maybe</code> is a type which takes one parameter.
|
||||||
Its definition is:</p>
|
Its definition is:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -2432,35 +2433,36 @@ main = <span class="Keyword">do</span>
|
||||||
<span class="Constant">Nothing</span> -> <span class="Entity">error</span> <span class="String"><span class="String">"</span>Bad format. Good Bye.<span class="String">"</span></span>
|
<span class="Constant">Nothing</span> -> <span class="Entity">error</span> <span class="String"><span class="String">"</span>Bad format. Good Bye.<span class="String">"</span></span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>In case of error, we prompt a nice error message.</p>
|
<p>In case of error, we display a nice error message.</p>
|
||||||
|
|
||||||
<p>Remark the type of each expression in the main’s do block remains of the form <code>IO a</code>.
|
<p>Note that the type of each expression in the main’s do block remains of the form <code>IO a</code>.
|
||||||
The only strange construction is <code>error</code>.
|
The only strange construction is <code>error</code>.
|
||||||
I’ll say <code>error msg</code> will simply take the needed type (here <code>IO ()</code>).</p>
|
I’ll say <code>error msg</code> will simply take the needed type (here <code>IO ()</code>).</p>
|
||||||
|
|
||||||
<p>One very important thing to note is the type of all the defined function.
|
<p>One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains <code>IO</code> in its type: <code>main</code>.
|
There is only one function which contains <code>IO</code> in its type: <code>main</code>.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use <code>getListFromString</code> which is pure.
|
But main uses <code>getListFromString</code> which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.</p>
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.</p>
|
||||||
|
|
||||||
<p>Why purity matters?
|
<p>Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:</p>
|
I certainly forget many advantages, but the three main reasons are:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>It is far easier to think about pure code than impure one.</li>
|
<li>It is far easier to think about pure code than impure one.</li>
|
||||||
<li>Purity protect you from all hard to reproduce bugs due to border effects.</li>
|
<li>Purity protects you from all the hard to reproduce bugs due to side effects.</li>
|
||||||
<li>You can evaluate pure functions in any order or in parallel without risk.</li>
|
<li>You can evaluate pure functions in any order or in parallel without risk.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>This is why, you should generally put as most code as possible in pure functions.</p>
|
<p>This is why you should generally put as most code as possible inside pure functions.</p>
|
||||||
|
|
||||||
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a></p>
|
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a></p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<p><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a></p>
|
<p><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a></p>
|
||||||
|
|
||||||
<p>Our next evolution will be to ask the user again and again until it enters a valid answer.</p>
|
<p>Our next evolution will be to prompt the user again and again until she enters a valid answer.</p>
|
||||||
|
|
||||||
<p>We keep the first part:</p>
|
<p>We keep the first part:</p>
|
||||||
|
|
||||||
|
@ -2476,7 +2478,7 @@ maybeRead s = <span class="Keyword">case</span> <span class="Entity">reads</span
|
||||||
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>Now, we create a function which will ask the user for an integer list
|
<p>Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.</p>
|
until the input is right.</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -2492,7 +2494,7 @@ askUser = <span class="Keyword">do</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>This function is of type <code>IO [Integer]</code>.
|
<p>This function is of type <code>IO [Integer]</code>.
|
||||||
Such a type means, that we retrieved a value of type <code>[Integer]</code> through some IO actions.
|
Such a type means that we retrieved a value of type <code>[Integer]</code> through some IO actions.
|
||||||
Some people might explain while waving their hands: </p>
|
Some people might explain while waving their hands: </p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@ -2501,7 +2503,7 @@ Some people might explain while waving their hands: </p>
|
||||||
|
|
||||||
<p>If you want to understand the details behind all of this, you’ll have to read the next section.
|
<p>If you want to understand the details behind all of this, you’ll have to read the next section.
|
||||||
But sincerely, if you just want to <em>use</em> IO.
|
But sincerely, if you just want to <em>use</em> IO.
|
||||||
Just exercise a little and remember to think about the type.</p>
|
Just practice a little and remember to think about the type.</p>
|
||||||
|
|
||||||
<p>Finally our main function is quite simpler:</p>
|
<p>Finally our main function is quite simpler:</p>
|
||||||
|
|
||||||
|
@ -2514,25 +2516,25 @@ main = <span class="Keyword">do</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>We have finished with our introduction to <code>IO</code>.
|
<p>We have finished with our introduction to <code>IO</code>.
|
||||||
This was quite a fast. Here are the main things to remind:</p>
|
This was quite fast. Here are the main things to remember:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>in the <code>do</code> bloc, each expression must have the type <code>IO a</code>.
|
<li>in the <code>do</code> bloc, each expression must have the type <code>IO a</code>.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, <code>getLine</code>, <code>print</code>, <code>putStrLn</code>, etc…</li>
|
For example, <code>getLine</code>, <code>print</code>, <code>putStrLn</code>, etc…</li>
|
||||||
<li>Try to externalize the pure function as much as possible. </li>
|
<li>Try to externalize the pure functions as much as possible.</li>
|
||||||
<li>the <code>IO a</code> type means: an IO <em>action</em> which return an element of type <code>a</code>.
|
<li>the <code>IO a</code> type means: an IO <em>action</em> which returns an element of type <code>a</code>.
|
||||||
<code>IO</code> represent action; under the hood, <code>IO a</code> is the type of a function.
|
<code>IO</code> represents actions; under the hood, <code>IO a</code> is the type of a function.
|
||||||
Read the next section if you are curious.</li>
|
Read the next section if you are curious.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>If you exercise a bit, you should be able to <em>use</em> <code>IO</code>.</p>
|
<p>If you practice a bit, you should be able to <em>use</em> <code>IO</code>.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><em>Exercises</em>:</p>
|
<p><em>Exercises</em>:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Make a program that sum all its argument. Hint: use the function <code>getArgs</code>.</li>
|
<li>Make a program that sums all of its arguments. Hint: use the function <code>getArgs</code>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -2545,14 +2547,14 @@ Read the next section if you are curious.</li>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Here is a <span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span> for this section.</p>
|
<p>Here is a <span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span> for this section.</p>
|
||||||
|
|
||||||
<p>To separate pure from impure part,
|
<p>To separate pure and impure parts,
|
||||||
the main is defined as a function
|
<code>main</code> is defined as a function
|
||||||
which modify the state of the world</p>
|
which modifies the state of the world</p>
|
||||||
|
|
||||||
<pre><code>main :: World -> World
|
<pre><code>main :: World -> World
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>A function is granted to have side effect only if it gets this value.
|
<p>A function is guaranteed to have side effects only if it has this type.
|
||||||
But look at a typical main function:</p>
|
But look at a typical main function:</p>
|
||||||
|
|
||||||
<pre><code>main w0 =
|
<pre><code>main w0 =
|
||||||
|
@ -2563,16 +2565,16 @@ But look at a typical main function:</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>We have a lot of temporary elements (here <code>w1</code>, <code>w2</code> and <code>w3</code>)
|
<p>We have a lot of temporary elements (here <code>w1</code>, <code>w2</code> and <code>w3</code>)
|
||||||
which must be passed to the next action.</p>
|
which must be passed on to the next action.</p>
|
||||||
|
|
||||||
<p>We create a function <code>bind</code> or <code>(>>=)</code>.
|
<p>We create a function <code>bind</code> or <code>(>>=)</code>.
|
||||||
With <code>bind</code> we need no more temporary name.</p>
|
With <code>bind</code> we don’t need temporary names anymore.</p>
|
||||||
|
|
||||||
<pre><code>main =
|
<pre><code>main =
|
||||||
action1 >>= action2 >>= action3 >>= action4
|
action1 >>= action2 >>= action3 >>= action4
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Bonus: Haskell has a syntactical sugar for us:</p>
|
<p>Bonus: Haskell has syntactical sugar for us:</p>
|
||||||
|
|
||||||
<pre><code>main = do
|
<pre><code>main = do
|
||||||
v1 <- action1
|
v1 <- action1
|
||||||
|
@ -2582,11 +2584,11 @@ With <code>bind</code> we need no more temporary name.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>Why did we used some strange syntax, and what exactly is this <code>IO</code> type.
|
<p>Why did we use this strange syntax, and what exactly is this <code>IO</code> type?
|
||||||
It looks a bit like magic.</p>
|
It looks a bit like magic.</p>
|
||||||
|
|
||||||
<p>For now let’s just forget about all the pure part of our program, and focus
|
<p>For now let’s just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:</p>
|
on the impure parts:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||||||
|
@ -2605,31 +2607,31 @@ main = <span class="Keyword">do</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>First remark; it looks like an imperative structure.
|
<p>First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a <code>while</code> in Haskell.
|
For example, if you wish you could create a <code>while</code> in Haskell.
|
||||||
In fact, for dealing with <code>IO</code>, imperative style is generally more appropriate.</p>
|
In fact, for dealing with <code>IO</code>, imperative style is generally more appropriate.</p>
|
||||||
|
|
||||||
<p>But, you should had remarked the notation is a bit unusual.
|
<p>But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.</p>
|
Here is why, in detail.</p>
|
||||||
|
|
||||||
<p>In an impure language, the state of the world can be seen as a huge hidden global variable.
|
<p>In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.</p>
|
The fact that a file exists or not can be seen as different states of the world.</p>
|
||||||
|
|
||||||
<p>For Haskell this state is not hidden.
|
<p>For Haskell this state is not hidden.
|
||||||
It is explicitly said <code>main</code> is a function that <em>potentially</em> change the state of the world.
|
It is explicitly said <code>main</code> is a function that <em>potentially</em> changes the state of the world.
|
||||||
It’s type is then something like:</p>
|
Its type is then something like:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">main</span> :: <span class="Constant">World</span> -> <span class="Constant">World</span>
|
<span class="Entity">main</span> :: <span class="Constant">World</span> -> <span class="Constant">World</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Not all function could have access to this variable.
|
<p>Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn’t provided to should be pure<sup id="fnref:032001"><a href="#fn:032001" rel="footnote">6</a></sup>.</p>
|
Functions to which the world variable isn’t provided are pure<sup id="fnref:032001"><a href="#fn:032001" rel="footnote">6</a></sup>.</p>
|
||||||
|
|
||||||
<p>Haskell consider the state of the world is an input variable for <code>main</code>.
|
<p>Haskell considers the state of the world as an input variable to <code>main</code>.
|
||||||
But the real type of main is closer to this one<sup id="fnref:032002"><a href="#fn:032002" rel="footnote">7</a></sup>:</p>
|
But the real type of main is closer to this one<sup id="fnref:032002"><a href="#fn:032002" rel="footnote">7</a></sup>:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -2648,17 +2650,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>First, we remark, that all function which have side effect must have the type:</p>
|
<p>First, we note that all functions which have side effects must have the type:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Constant">World</span> -> (a,<span class="Constant">World</span>)
|
<span class="Constant">World</span> -> (a,<span class="Constant">World</span>)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Where <code>a</code> is the type of result.
|
<p>Where <code>a</code> is the type of the result.
|
||||||
For example, a <code>getChar</code> function should have the type <code>World -> (Char,World)</code>.</p>
|
For example, a <code>getChar</code> function should have the type <code>World -> (Char,World)</code>.</p>
|
||||||
|
|
||||||
<p>Another thing to remark is the trick to fix the order of evaluation.
|
<p>Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate <code>f a b</code>, you generally have many choices: </p>
|
In Haskell, in order to evaluate <code>f a b</code>, you have many choices:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>first eval <code>a</code> then <code>b</code> then <code>f a b</code></li>
|
<li>first eval <code>a</code> then <code>b</code> then <code>f a b</code></li>
|
||||||
|
@ -2683,7 +2685,7 @@ Under the hood, <code>print</code> will evaluate as:</p>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Now, if you look at the style of the main function, it is clearly awkward.
|
<p>Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let’s try to make the same to the askUser function:</p>
|
Let’s try to do the same to the askUser function:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">askUser</span> :: <span class="Constant">World</span> -> ([<span class="Constant">Integer</span>],<span class="Constant">World</span>)
|
<span class="Entity">askUser</span> :: <span class="Constant">World</span> -> ([<span class="Constant">Integer</span>],<span class="Constant">World</span>)
|
||||||
|
@ -2718,9 +2720,9 @@ askUser w0 =
|
||||||
<p>This is similar, but awkward.
|
<p>This is similar, but awkward.
|
||||||
Look at all these temporary <code>w?</code> names.</p>
|
Look at all these temporary <code>w?</code> names.</p>
|
||||||
|
|
||||||
<p>The lesson, is, naive IO implementation in Pure functional language is awkward!</p>
|
<p>The lesson, is, naive IO implementation in Pure functional languages is awkward!</p>
|
||||||
|
|
||||||
<p>Fortunately, some have found a better way to handle this problem.
|
<p>Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:</p>
|
Each line is of the form:</p>
|
||||||
|
|
||||||
|
@ -2736,8 +2738,7 @@ Each function <code>f</code> must have a type similar to:</p>
|
||||||
<span class="Entity">f</span> :: <span class="Constant">World</span> -> (<span class="Variable">a,World</span>)
|
<span class="Entity">f</span> :: <span class="Constant">World</span> -> (<span class="Variable">a,World</span>)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Not only this, but we can also remark we use them always
|
<p>Not only this, but we can also note that we always follow the same usage pattern:</p>
|
||||||
with the following general pattern:</p>
|
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">let</span> (y,w1) = action1 w0 <span class="Keyword">in</span>
|
<span class="Keyword">let</span> (y,w1) = action1 w0 <span class="Keyword">in</span>
|
||||||
|
@ -2746,7 +2747,7 @@ with the following general pattern:</p>
|
||||||
...
|
...
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Each action can take 0 to some parameters.
|
<p>Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.</p>
|
And in particular, each action can take a parameter from the result of a line above.</p>
|
||||||
|
|
||||||
<p>For example, we could also have:</p>
|
<p>For example, we could also have:</p>
|
||||||
|
@ -2761,7 +2762,7 @@ And in particular, each action can take a parameter from the result of a line ab
|
||||||
<p>And of course <code>actionN w :: (World) -> (a,World)</code>.</p>
|
<p>And of course <code>actionN w :: (World) -> (a,World)</code>.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>IMPORTANT, there are only two important pattern for us:</p>
|
<p>IMPORTANT, there are only two important patterns to consider:</p>
|
||||||
|
|
||||||
<pre><code>let (x,w1) = action1 w0 in
|
<pre><code>let (x,w1) = action1 w0 in
|
||||||
let (y,w2) = action2 x w1 in
|
let (y,w2) = action2 x w1 in
|
||||||
|
@ -2776,7 +2777,7 @@ let (y,w2) = action2 w1 in
|
||||||
|
|
||||||
<p><img alt="Jocker pencil trick" src="/Scratch/img/blog/Haskell-the-Hard-Way/jocker_pencil_trick.jpg" class="left" /></p>
|
<p><img alt="Jocker pencil trick" src="/Scratch/img/blog/Haskell-the-Hard-Way/jocker_pencil_trick.jpg" class="left" /></p>
|
||||||
|
|
||||||
<p>Now, we will make a magic trick.
|
<p>Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol “disappear”.
|
We will make the temporary world symbol “disappear”.
|
||||||
We will <code>bind</code> the two lines.
|
We will <code>bind</code> the two lines.
|
||||||
Let’s define the <code>bind</code> function.
|
Let’s define the <code>bind</code> function.
|
||||||
|
@ -2802,18 +2803,18 @@ Now let’s rename it for clarity:</p>
|
||||||
<span class="Entity">print</span> :: <span class="Constant">Show</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">IO</span> ()
|
<span class="Entity">print</span> :: <span class="Constant">Show</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">IO</span> ()
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p><code>getLine</code> is an IO action which take a world as parameter and return a couple <code>(String,World)</code>.
|
<p><code>getLine</code> is an IO action which takes a world as parameter and returns a couple <code>(String,World)</code>.
|
||||||
Which can be said as: <code>getLine</code> is of type <code>IO String</code>.
|
Which can be summarized as: <code>getLine</code> is of type <code>IO String</code>.
|
||||||
Which we also see as, an IO action which will return a String “embeded inside an IO”.</p>
|
Which we also see as, an IO action which will return a String “embeded inside an IO”.</p>
|
||||||
|
|
||||||
<p>The function <code>print</code> is also interresting.
|
<p>The function <code>print</code> is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type <code>((),World)</code>.
|
It then returns a couple of type <code>((),World)</code>.
|
||||||
This means it changes the world state, but don’t give anymore data.</p>
|
This means it changes the state of the world, but doesn’t yield anymore data.</p>
|
||||||
|
|
||||||
<p>This type help us simplify the type of <code>bind</code>:</p>
|
<p>This type helps us simplify the type of <code>bind</code>:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">bind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span>
|
<span class="Entity">bind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span>
|
||||||
|
@ -2839,7 +2840,7 @@ This means it changes the world state, but don’t give anymore data.</p>
|
||||||
(y,w2) :: <span class="Constant">IO</span> b
|
(y,w2) :: <span class="Constant">IO</span> b
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Doesn’t seem familiar?</p>
|
<p>Doesn’t it seem familiar?</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -2849,7 +2850,7 @@ This means it changes the world state, but don’t give anymore data.</p>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>The idea is to hide the World argument with this function. Let’s go:
|
<p>The idea is to hide the World argument with this function. Let’s go:
|
||||||
As example imagine if we wanted to simulate:</p>
|
As an example imagine if we wanted to simulate:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
||||||
|
@ -2864,7 +2865,7 @@ As example imagine if we wanted to simulate:</p>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>As print is of type (World → ((),World)), we know res = () (null type).
|
<p>As print is of type (World → ((),World)), we know res = () (null type).
|
||||||
If you didn’t saw what was magic here, let’s try with three lines this time.</p>
|
If you didn’t see what was magic here, let’s try with three lines this time.</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
||||||
|
@ -2881,8 +2882,8 @@ If you didn’t saw what was magic here, let’s try with three lines th
|
||||||
<span class="Entity">print</span> (line1 ++ line2)))
|
<span class="Entity">print</span> (line1 ++ line2)))
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Didn’t you remark something?
|
<p>Didn’t you notice something?
|
||||||
Yes, there isn’t anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is <em>MA</em>. <em>GIC</em>.</p>
|
This is <em>MA</em>. <em>GIC</em>.</p>
|
||||||
|
|
||||||
<p>We can use a better notation.
|
<p>We can use a better notation.
|
||||||
|
@ -2897,7 +2898,7 @@ Let’s use <code>(>>=)</code> instead of <code>bind</code>.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Ho Ho Ho! Happy Christmas Everyone!
|
<p>Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:</p>
|
Haskell has made syntactical sugar for us:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">do</span>
|
<span class="Keyword">do</span>
|
||||||
|
@ -2918,8 +2919,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
<p>Note you can use <code>x</code> in <code>action2</code> and <code>x</code> and <code>y</code> in <code>action3</code>.</p>
|
<p>Note you can use <code>x</code> in <code>action2</code> and <code>x</code> and <code>y</code> in <code>action3</code>.</p>
|
||||||
|
|
||||||
<p>But what for line not using the <code><-</code>?
|
<p>But what about the lines not using the <code><-</code>?
|
||||||
Easy another function <code>blindBind</code>:</p>
|
Easy, another function <code>blindBind</code>:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">blindBind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">b</span> -> <span class="Constant">IO</span> <span class="Variable">b</span>
|
<span class="Entity">blindBind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">b</span> -> <span class="Constant">IO</span> <span class="Variable">b</span>
|
||||||
|
@ -2927,7 +2928,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>I didn’t simplified this definition for clarity purpose.
|
<p>I didn’t simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we’ll use the <code>(>>)</code> operator.</p>
|
Of course we can use a better notation, we’ll use the <code>(>>)</code> operator.</p>
|
||||||
|
|
||||||
<p>And</p>
|
<p>And</p>
|
||||||
|
@ -2954,7 +2955,7 @@ action3
|
||||||
putInIO x = <span class="Constant">IO</span> (\w -> (x,w))
|
putInIO x = <span class="Constant">IO</span> (\w -> (x,w))
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>This is the general way to put pure value inside the “IO context”.
|
<p>This is the general way to put pure values inside the “IO context”.
|
||||||
The general name for <code>putInIO</code> is <code>return</code>.
|
The general name for <code>putInIO</code> is <code>return</code>.
|
||||||
This is quite a bad name when you learn Haskell. <code>return</code> is very different from what you might be used to. </p>
|
This is quite a bad name when you learn Haskell. <code>return</code> is very different from what you might be used to. </p>
|
||||||
|
|
||||||
|
@ -3006,7 +3007,7 @@ main = askUser >>=
|
||||||
\list -> <span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
\list -> <span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>You can compile this code to verify it continues to work.</p>
|
<p>You can compile this code to verify it keeps working.</p>
|
||||||
|
|
||||||
<p>Imagine what it would look like without the <code>(>>)</code> and <code>(>>=)</code>.</p>
|
<p>Imagine what it would look like without the <code>(>>)</code> and <code>(>>=)</code>.</p>
|
||||||
|
|
||||||
|
@ -3017,11 +3018,11 @@ main = askUser >>=
|
||||||
|
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<p><img alt="Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document." src="/Scratch/img/blog/Haskell-the-Hard-Way/dali_reve.jpg" /></p>
|
<p><img alt="Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document." src="/Scratch/img/blog/Haskell-the-Hard-Way/dali_reve.jpg" /></p>
|
||||||
|
|
||||||
<p>Now the secret can be revealed: <code>IO</code> is a <em>monad</em>.
|
<p>Now the secret can be revealed: <code>IO</code> is a <em>monad</em>.
|
||||||
Being a monad means you have access to some syntactical sugar with the <code>do</code> notation.
|
Being a monad means you have access to some syntactical sugar with the <code>do</code> notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.</p>
|
But mainly, you have access to a coding pattern which will ease the flow of your code.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><strong>Important remarks</strong>:</p>
|
<p><strong>Important remarks</strong>:</p>
|
||||||
|
@ -3058,14 +3059,14 @@ Here is how the type class <code>Monad</code> is declared (mostly):</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>the keyword <code>class</code> is not your friend.
|
<li>the keyword <code>class</code> is not your friend.
|
||||||
A Haskell class is <em>not</em> a class like in object model.
|
A Haskell class is <em>not</em> a class like in object model.
|
||||||
A Haskell class has a lot similarities with Java interfaces.
|
A Haskell class has a lot of similarities with Java interfaces.
|
||||||
A better word should have been <code>typeclass</code>.
|
A better word should have been <code>typeclass</code>.
|
||||||
That means a set of types.
|
That means a set of types.
|
||||||
For a type to belong to a class, all function of the class must be provided for this type.</li>
|
For a type to belong to a class, all functions of the class must be provided for this type.</li>
|
||||||
<li>In this particular example of type class, the type <code>m</code> must be a type that take an argument.
|
<li>In this particular example of type class, the type <code>m</code> must be a type that takes an argument.
|
||||||
for example <code>IO a</code>, but also <code>Maybe a</code>, <code>[a]</code>, etc…</li>
|
for example <code>IO a</code>, but also <code>Maybe a</code>, <code>[a]</code>, etc…</li>
|
||||||
<li>
|
<li>
|
||||||
<p>To be a useful monad, your function must obey some rule.
|
<p>To be a useful monad, your function must obey some rules.
|
||||||
If your construction does not obey these rules strange things might happens:</p>
|
If your construction does not obey these rules strange things might happens:</p>
|
||||||
|
|
||||||
<pre><code>return a >>= k == k a
|
<pre><code>return a >>= k == k a
|
||||||
|
@ -3078,13 +3079,13 @@ m >>= (\x -> k x >>= h) == (m >>= k) >>= h
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
<p>There exists a lot of different type that are instance of <code>Monad</code>.
|
<p>There are a lot of different types that are instance of <code>Monad</code>.
|
||||||
One of the easiest to describe is <code>Maybe</code>.
|
One of the easiest to describe is <code>Maybe</code>.
|
||||||
If you have a sequence of <code>Maybe</code> values, you could use monad to manipulate them.
|
If you have a sequence of <code>Maybe</code> values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep <code>if..then..else..</code> constructions.</p>
|
It is particularly useful to remove very deep <code>if..then..else..</code> constructions.</p>
|
||||||
|
|
||||||
<p>Imagine a complex bank operation. You are eligible to gain about 700€ only
|
<p>Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.</p>
|
if you can afford to follow a list of operations without being negative.</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -3125,7 +3126,7 @@ main = <span class="Keyword">do</span>
|
||||||
<hr />
|
<hr />
|
||||||
<p><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a></p>
|
<p><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a></p>
|
||||||
|
|
||||||
<p>Now, let’s make it better using Maybe and the fact it is a Monad</p>
|
<p>Now, let’s make it better using Maybe and the fact that it is a Monad</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -3182,7 +3183,7 @@ main = <span class="Keyword">do</span>
|
||||||
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> Nothing</span>
|
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> Nothing</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>We have proved Monad are nice to make our code more elegant.
|
<p>We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for <code>Maybe</code> can be used
|
Note this idea of code organization, in particular for <code>Maybe</code> can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.</p>
|
In fact, this is the kind of construction we make naturally.</p>
|
||||||
|
@ -3192,7 +3193,7 @@ In fact, this is the kind of construction we make naturally.</p>
|
||||||
|
|
||||||
<p>The first element in the sequence being evaluated to <code>Nothing</code> will stop
|
<p>The first element in the sequence being evaluated to <code>Nothing</code> will stop
|
||||||
the complete evaluation.
|
the complete evaluation.
|
||||||
That means, you don’t execute all lines.
|
This means you don’t execute all lines.
|
||||||
You have this for free, thanks to laziness.</p>
|
You have this for free, thanks to laziness.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -3209,7 +3210,7 @@ But now a cooler example, lists.</p>
|
||||||
|
|
||||||
<p><img alt="Golconde de Magritte" src="/Scratch/img/blog/Haskell-the-Hard-Way/golconde.jpg" /></p>
|
<p><img alt="Golconde de Magritte" src="/Scratch/img/blog/Haskell-the-Hard-Way/golconde.jpg" /></p>
|
||||||
|
|
||||||
<p>The list monad help us to simulate non deterministic computation.
|
<p>The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:</p>
|
Here we go:</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -3245,8 +3246,8 @@ main = <span class="Keyword">do</span>
|
||||||
4*x + 2*y < z ]
|
4*x + 2*y < z ]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>I won’t list all the monads, but there is a lot of monads.
|
<p>I won’t list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for: </p>
|
In particular, monad are very useful for: </p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -3261,6 +3262,9 @@ In particular, monad are very useful for: </p>
|
||||||
<p>If you have followed me until here, then you’ve done it!
|
<p>If you have followed me until here, then you’ve done it!
|
||||||
You know monads<sup id="fnref:03021301"><a href="#fn:03021301" rel="footnote">8</a></sup>!</p>
|
You know monads<sup id="fnref:03021301"><a href="#fn:03021301" rel="footnote">8</a></sup>!</p>
|
||||||
|
|
||||||
|
<p>and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.</p>
|
||||||
|
|
||||||
<p><a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a></p>
|
<p><a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a></p>
|
||||||
|
|
||||||
<h2 id="appendix">Appendix</h2>
|
<h2 id="appendix">Appendix</h2>
|
||||||
|
@ -3273,8 +3277,9 @@ It is just here to discuss some details further.</p>
|
||||||
|
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
<p>In the section <a href="#infinite-structures">Infinite Structures</a> we saw some simple construction.
|
<p>In the section <a href="#infinite-structures">Infinite Structures</a> we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:</p>
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:</p>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>no duplicate node value</li>
|
<li>no duplicate node value</li>
|
||||||
|
@ -3282,7 +3287,7 @@ Unfortunately we removed two properties of our tree:</p>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>In this section we will try to keep the first property.
|
<p>In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we’ll discuss on how to
|
Concerning the second one, we must relax it but we’ll discuss how to
|
||||||
keep it as much as possible.</p>
|
keep it as much as possible.</p>
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -3345,7 +3350,7 @@ This code is mostly the same as the one in the [tree section](#trees).
|
||||||
shuffle = <span class="Entity">map</span> (\x -> (x*3123) <span class="Entity"><span class="Entity">`</span>mod<span class="Entity">`</span></span> 4331) [1..]
|
shuffle = <span class="Entity">map</span> (\x -> (x*3123) <span class="Entity"><span class="Entity">`</span>mod<span class="Entity">`</span></span> 4331) [1..]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>Just as reminder here are the definition of <code>treeFromList</code></p>
|
<p>Just as a reminder, here is the definition of <code>treeFromList</code></p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -3411,17 +3416,17 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>will loop forever.
|
<p>will loop forever.
|
||||||
Simply because, it will try to access the head of <code>filter (<1) [2..]</code>.
|
Simply because it will try to access the head of <code>filter (<1) [2..]</code>.
|
||||||
But filter is not smart enought to understand that the result is the empty list.</p>
|
But <code>filter</code> is not smart enought to understand that the result is the empty list.</p>
|
||||||
|
|
||||||
<p>Nonetheless, it is still a very cool example of what non strict program has to offer.</p>
|
<p>Nonetheless, it is still a very cool example of what non strict programs have to offer.</p>
|
||||||
|
|
||||||
<p>Left as an exercise to the reader:</p>
|
<p>Left as an exercise to the reader:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Could you prove that there exists some number <code>n</code> such that <code>treeTakeDepth n (treeFromList shuffle)</code> will enter in an infinite loop.</li>
|
<li>Prove the existence of a number <code>n</code> so that <code>treeTakeDepth n (treeFromList shuffle)</code> will enter an infinite loop.</li>
|
||||||
<li>Find an upper bound for <code>n</code>.</li>
|
<li>Find an upper bound for <code>n</code>.</li>
|
||||||
<li>Prove there is no <code>shuffle</code> list such that, for any depth, the program ends.</li>
|
<li>Prove there is no <code>shuffle</code> list so that, for any depth, the program ends.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p><a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a></p>
|
<p><a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a></p>
|
||||||
|
@ -3626,13 +3631,13 @@ treeFromList' (x:xs) n = <span class="Constant">Node</span> x left right
|
||||||
<p>Which itself is very similar to the javascript <code>eval</code> on a string containing JSON).<a href="#fnref:1" rel="reference">↩</a></p>
|
<p>Which itself is very similar to the javascript <code>eval</code> on a string containing JSON).<a href="#fnref:1" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="fn:032001">
|
<li id="fn:032001">
|
||||||
<p>There are some <em>unsafe</em> exception to this rule. But you shouldn’t see such usage on a real application except might be for some debugging purpose.<a href="#fnref:032001" rel="reference">↩</a></p>
|
<p>There are some <em>unsafe</em> exceptions to this rule. But you shouldn’t see such use on a real application except maybe for debugging purpose.<a href="#fnref:032001" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="fn:032002">
|
<li id="fn:032002">
|
||||||
<p>For the curious the real type is <code>data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}</code>. All the <code>#</code> as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.<a href="#fnref:032002" rel="reference">↩</a></p>
|
<p>For the curious the real type is <code>data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}</code>. All the <code>#</code> as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.<a href="#fnref:032002" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="fn:03021301">
|
<li id="fn:03021301">
|
||||||
<p>Well, you’ll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.<a href="#fnref:03021301" rel="reference">↩</a></p>
|
<p>Well, you’ll certainly need to practice a bit to get used to them<a href="#fnref:03021301" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -103,7 +103,7 @@
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Copyright ©, Yann Esposito</a>
|
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/">Copyright ©, Yann Esposito</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="lastmod">
|
<div id="lastmod">
|
||||||
Modified: 04/11/2012
|
Modified: 04/17/2012
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Entirely done with
|
Entirely done with
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
Congratulation to get so far!
|
Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.
|
Now, some of the really hardcore stuff can start.
|
||||||
|
|
||||||
If you are like me, you should get the functional style.
|
If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don't really understand were to start to make a real program.
|
But you also don't really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:
|
And in particular:
|
||||||
|
|
||||||
- How do you deal with effects?
|
- How do you deal with effects?
|
||||||
- Why is there a strange imperative-like notation for dealing with IO?
|
- Why is there a strange imperative-like notation for dealing with IO?
|
||||||
|
|
||||||
Be prepared, answer might be difficult to get.
|
Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.
|
But they all be very rewarding.
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
> <%=tldr%>
|
> <%=tldr%>
|
||||||
>
|
>
|
||||||
> A typical function doing `IO` look a lot like an imperative language:
|
> A typical function doing `IO` looks a lot like an imperative program:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> f :: IO a
|
> f :: IO a
|
||||||
|
@ -23,15 +23,15 @@
|
||||||
> - `action3 :: IO c`
|
> - `action3 :: IO c`
|
||||||
> - `action4 x y :: IO a`
|
> - `action4 x y :: IO a`
|
||||||
> - `x :: b`, `y :: c`
|
> - `x :: b`, `y :: c`
|
||||||
> - Few objects have the type `IO a`, this should help you to choose.
|
> - Few objects have the type `IO a`, this should help you choose.
|
||||||
> In particular you cannot use pure function directly here.
|
> In particular you cannot use pure functions directly here.
|
||||||
> To use pure function you could do `action2 (purefunction x)` for example.
|
> To use pure functions you could do `action2 (purefunction x)` for example.
|
||||||
|
|
||||||
In this section, I will explain how to use IO, not how they work.
|
In this section, I will explain how to use IO, not how it works.
|
||||||
You'll see how Haskell separate pure from impure part of the program.
|
You'll see how Haskell separates the pure from the impure parts of the program.
|
||||||
|
|
||||||
Don't stop because you're trying to understand the details of the syntax.
|
Don't stop because you're trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.
|
Answers will come in the next section.
|
||||||
|
|
||||||
What to achieve?
|
What to achieve?
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
Or more interestingly, we remark each expression in the `do` block has a type of `IO a`.
|
Or more interestingly, we note that each expression in the `do` block has a type of `IO a`.
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -64,7 +64,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
We should also remark the effect of the `<-` symbol.
|
We should also pay attention to the effect of the `<-` symbol.
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
do
|
do
|
||||||
|
@ -73,8 +73,8 @@ do
|
||||||
|
|
||||||
If `something :: IO a` then `x :: a`.
|
If `something :: IO a` then `x :: a`.
|
||||||
|
|
||||||
Another important remark to use `IO`.
|
Another important note about using `IO`.
|
||||||
All line in a do block must have one of the two forms:
|
All lines in a do block must be of one of the two forms:
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
action1 :: IO a
|
action1 :: IO a
|
||||||
|
@ -89,5 +89,5 @@ value <- action2 -- where
|
||||||
-- value :: b
|
-- value :: b
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
These two kind of line will correspond to two different way of sequencing actions.
|
These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.
|
The meaning of this sentence should be clearer by the end of the next section.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Now let's see how this behave.
|
Now let's see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let's try:
|
Let's try:
|
||||||
|
|
||||||
|
@ -12,14 +12,14 @@ Let's try:
|
||||||
Argh! An evil error message and a crash!
|
Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.
|
The first evolution will be to answer with a more friendly message.
|
||||||
|
|
||||||
For this, we must detect, something went wrong.
|
In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type `Maybe`.
|
Use the type `Maybe`.
|
||||||
It is a very common type in Haskell.
|
It is a very common type in Haskell.
|
||||||
|
|
||||||
> import Data.Maybe
|
> import Data.Maybe
|
||||||
|
|
||||||
What is this thing? Maybe is a type which takes one parameter.
|
What is this thing? `Maybe` is a type which takes one parameter.
|
||||||
Its definition is:
|
Its definition is:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -61,23 +61,24 @@ We simply have to test the value in our main function.
|
||||||
> Just l -> print (sum l)
|
> Just l -> print (sum l)
|
||||||
> Nothing -> error "Bad format. Good Bye."
|
> Nothing -> error "Bad format. Good Bye."
|
||||||
|
|
||||||
In case of error, we prompt a nice error message.
|
In case of error, we display a nice error message.
|
||||||
|
|
||||||
Remark the type of each expression in the main's do block remains of the form `IO a`.
|
Note that the type of each expression in the main's do block remains of the form `IO a`.
|
||||||
The only strange construction is `error`.
|
The only strange construction is `error`.
|
||||||
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
I'll say `error msg` will simply take the needed type (here `IO ()`).
|
||||||
|
|
||||||
One very important thing to note is the type of all the defined function.
|
One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains `IO` in its type: `main`.
|
There is only one function which contains `IO` in its type: `main`.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use `getListFromString` which is pure.
|
But main uses `getListFromString` which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.
|
||||||
|
|
||||||
Why purity matters?
|
Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:
|
I certainly forget many advantages, but the three main reasons are:
|
||||||
|
|
||||||
- It is far easier to think about pure code than impure one.
|
- It is far easier to think about pure code than impure one.
|
||||||
- Purity protect you from all hard to reproduce bugs due to border effects.
|
- Purity protects you from all the hard to reproduce bugs due to side effects.
|
||||||
- You can evaluate pure functions in any order or in parallel without risk.
|
- You can evaluate pure functions in any order or in parallel without risk.
|
||||||
|
|
||||||
This is why, you should generally put as most code as possible in pure functions.
|
This is why you should generally put as most code as possible inside pure functions.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Our next evolution will be to ask the user again and again until it enters a valid answer.
|
Our next evolution will be to prompt the user again and again until she enters a valid answer.
|
||||||
|
|
||||||
We keep the first part:
|
We keep the first part:
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ We keep the first part:
|
||||||
> getListFromString :: String -> Maybe [Integer]
|
> getListFromString :: String -> Maybe [Integer]
|
||||||
> getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
> getListFromString str = maybeRead $ "[" ++ str ++ "]"
|
||||||
|
|
||||||
Now, we create a function which will ask the user for an integer list
|
Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.
|
until the input is right.
|
||||||
|
|
||||||
> askUser :: IO [Integer]
|
> askUser :: IO [Integer]
|
||||||
|
@ -24,14 +24,14 @@ until the input is right.
|
||||||
> Nothing -> askUser
|
> Nothing -> askUser
|
||||||
|
|
||||||
This function is of type `IO [Integer]`.
|
This function is of type `IO [Integer]`.
|
||||||
Such a type means, that we retrieved a value of type `[Integer]` through some IO actions.
|
Such a type means that we retrieved a value of type `[Integer]` through some IO actions.
|
||||||
Some people might explain while waving their hands:
|
Some people might explain while waving their hands:
|
||||||
|
|
||||||
> «This is an `[Integer]` inside an `IO`»
|
> «This is an `[Integer]` inside an `IO`»
|
||||||
|
|
||||||
If you want to understand the details behind all of this, you'll have to read the next section.
|
If you want to understand the details behind all of this, you'll have to read the next section.
|
||||||
But sincerely, if you just want to _use_ IO.
|
But sincerely, if you just want to _use_ IO.
|
||||||
Just exercise a little and remember to think about the type.
|
Just practice a little and remember to think about the type.
|
||||||
|
|
||||||
Finally our main function is quite simpler:
|
Finally our main function is quite simpler:
|
||||||
|
|
||||||
|
@ -41,18 +41,18 @@ Finally our main function is quite simpler:
|
||||||
> print $ sum list
|
> print $ sum list
|
||||||
|
|
||||||
We have finished with our introduction to `IO`.
|
We have finished with our introduction to `IO`.
|
||||||
This was quite a fast. Here are the main things to remind:
|
This was quite fast. Here are the main things to remember:
|
||||||
|
|
||||||
- in the `do` bloc, each expression must have the type `IO a`.
|
- in the `do` bloc, each expression must have the type `IO a`.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, `getLine`, `print`, `putStrLn`, etc...
|
For example, `getLine`, `print`, `putStrLn`, etc...
|
||||||
- Try to externalize the pure function as much as possible.
|
- Try to externalize the pure functions as much as possible.
|
||||||
- the `IO a` type means: an IO _action_ which return an element of type `a`.
|
- the `IO a` type means: an IO _action_ which returns an element of type `a`.
|
||||||
`IO` represent action; under the hood, `IO a` is the type of a function.
|
`IO` represents actions; under the hood, `IO a` is the type of a function.
|
||||||
Read the next section if you are curious.
|
Read the next section if you are curious.
|
||||||
|
|
||||||
If you exercise a bit, you should be able to _use_ `IO`.
|
If you practice a bit, you should be able to _use_ `IO`.
|
||||||
|
|
||||||
> _Exercises_:
|
> _Exercises_:
|
||||||
>
|
>
|
||||||
> - Make a program that sum all its argument. Hint: use the function `getArgs`.
|
> - Make a program that sums all of its arguments. Hint: use the function `getArgs`.
|
||||||
|
|
|
@ -4,15 +4,15 @@
|
||||||
|
|
||||||
> Here is a <%=tldr%> for this section.
|
> Here is a <%=tldr%> for this section.
|
||||||
>
|
>
|
||||||
> To separate pure from impure part,
|
> To separate pure and impure parts,
|
||||||
> the main is defined as a function
|
> `main` is defined as a function
|
||||||
> which modify the state of the world
|
> which modifies the state of the world
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main :: World -> World
|
> main :: World -> World
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> A function is granted to have side effect only if it gets this value.
|
> A function is guaranteed to have side effects only if it has this type.
|
||||||
> But look at a typical main function:
|
> But look at a typical main function:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -24,17 +24,17 @@
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
> We have a lot of temporary elements (here `w1`, `w2` and `w3`)
|
||||||
> which must be passed to the next action.
|
> which must be passed on to the next action.
|
||||||
>
|
>
|
||||||
> We create a function `bind` or `(>>=)`.
|
> We create a function `bind` or `(>>=)`.
|
||||||
> With `bind` we need no more temporary name.
|
> With `bind` we don't need temporary names anymore.
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main =
|
> main =
|
||||||
> action1 >>= action2 >>= action3 >>= action4
|
> action1 >>= action2 >>= action3 >>= action4
|
||||||
> ~~~
|
> ~~~
|
||||||
>
|
>
|
||||||
> Bonus: Haskell has a syntactical sugar for us:
|
> Bonus: Haskell has syntactical sugar for us:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> main = do
|
> main = do
|
||||||
|
@ -45,11 +45,11 @@
|
||||||
> ~~~
|
> ~~~
|
||||||
|
|
||||||
|
|
||||||
Why did we used some strange syntax, and what exactly is this `IO` type.
|
Why did we use this strange syntax, and what exactly is this `IO` type?
|
||||||
It looks a bit like magic.
|
It looks a bit like magic.
|
||||||
|
|
||||||
For now let's just forget about all the pure part of our program, and focus
|
For now let's just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:
|
on the impure parts:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: IO [Integer]
|
askUser :: IO [Integer]
|
||||||
|
@ -68,33 +68,33 @@ main = do
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First remark; it looks like an imperative structure.
|
First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a `while` in Haskell.
|
For example, if you wish you could create a `while` in Haskell.
|
||||||
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
In fact, for dealing with `IO`, imperative style is generally more appropriate.
|
||||||
|
|
||||||
But, you should had remarked the notation is a bit unusual.
|
But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.
|
Here is why, in detail.
|
||||||
|
|
||||||
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.
|
The fact that a file exists or not can be seen as different states of the world.
|
||||||
|
|
||||||
For Haskell this state is not hidden.
|
For Haskell this state is not hidden.
|
||||||
It is explicitly said `main` is a function that _potentially_ change the state of the world.
|
It is explicitly said `main` is a function that _potentially_ changes the state of the world.
|
||||||
It's type is then something like:
|
Its type is then something like:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
main :: World -> World
|
main :: World -> World
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not all function could have access to this variable.
|
Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn't provided to should be pure[^032001].
|
Functions to which the world variable isn't provided are pure[^032001].
|
||||||
|
|
||||||
[^032001]: There are some _unsafe_ exception to this rule. But you shouldn't see such usage on a real application except might be for some debugging purpose.
|
[^032001]: There are some _unsafe_ exceptions to this rule. But you shouldn't see such use on a real application except maybe for debugging purpose.
|
||||||
|
|
||||||
Haskell consider the state of the world is an input variable for `main`.
|
Haskell considers the state of the world as an input variable to `main`.
|
||||||
But the real type of main is closer to this one[^032002]:
|
But the real type of main is closer to this one[^032002]:
|
||||||
|
|
||||||
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
[^032002]: For the curious the real type is `data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}`. All the `#` as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.
|
||||||
|
@ -115,17 +115,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
First, we remark, that all function which have side effect must have the type:
|
First, we note that all functions which have side effects must have the type:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
World -> (a,World)
|
World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Where `a` is the type of result.
|
Where `a` is the type of the result.
|
||||||
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
For example, a `getChar` function should have the type `World -> (Char,World)`.
|
||||||
|
|
||||||
Another thing to remark is the trick to fix the order of evaluation.
|
Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate `f a b`, you generally have many choices:
|
In Haskell, in order to evaluate `f a b`, you have many choices:
|
||||||
|
|
||||||
- first eval `a` then `b` then `f a b`
|
- first eval `a` then `b` then `f a b`
|
||||||
- first eval `b` then `a` then `f a b`.
|
- first eval `b` then `a` then `f a b`.
|
||||||
|
@ -146,7 +146,7 @@ Under the hood, `print` will evaluate as:
|
||||||
- evaluate as `((),new world id)`.
|
- evaluate as `((),new world id)`.
|
||||||
|
|
||||||
Now, if you look at the style of the main function, it is clearly awkward.
|
Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let's try to make the same to the askUser function:
|
Let's try to do the same to the askUser function:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
askUser :: World -> ([Integer],World)
|
askUser :: World -> ([Integer],World)
|
||||||
|
@ -181,9 +181,9 @@ askUser w0 =
|
||||||
This is similar, but awkward.
|
This is similar, but awkward.
|
||||||
Look at all these temporary `w?` names.
|
Look at all these temporary `w?` names.
|
||||||
|
|
||||||
The lesson, is, naive IO implementation in Pure functional language is awkward!
|
The lesson, is, naive IO implementation in Pure functional languages is awkward!
|
||||||
|
|
||||||
Fortunately, some have found a better way to handle this problem.
|
Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:
|
Each line is of the form:
|
||||||
|
|
||||||
|
@ -199,8 +199,7 @@ Each function `f` must have a type similar to:
|
||||||
f :: World -> (a,World)
|
f :: World -> (a,World)
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Not only this, but we can also remark we use them always
|
Not only this, but we can also note that we always follow the same usage pattern:
|
||||||
with the following general pattern:
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (y,w1) = action1 w0 in
|
let (y,w1) = action1 w0 in
|
||||||
|
@ -209,7 +208,7 @@ let (t,w3) = action3 w2 in
|
||||||
...
|
...
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Each action can take 0 to some parameters.
|
Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.
|
And in particular, each action can take a parameter from the result of a line above.
|
||||||
|
|
||||||
For example, we could also have:
|
For example, we could also have:
|
||||||
|
@ -223,7 +222,7 @@ let (_,w3) = action3 x z w2 in
|
||||||
|
|
||||||
And of course `actionN w :: (World) -> (a,World)`.
|
And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
> IMPORTANT, there are only two important pattern for us:
|
> IMPORTANT, there are only two important patterns to consider:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
> let (x,w1) = action1 w0 in
|
> let (x,w1) = action1 w0 in
|
||||||
|
@ -239,7 +238,7 @@ And of course `actionN w :: (World) -> (a,World)`.
|
||||||
|
|
||||||
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
<%= leftblogimage("jocker_pencil_trick.jpg","Jocker pencil trick") %>
|
||||||
|
|
||||||
Now, we will make a magic trick.
|
Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol "disappear".
|
We will make the temporary world symbol "disappear".
|
||||||
We will `bind` the two lines.
|
We will `bind` the two lines.
|
||||||
Let's define the `bind` function.
|
Let's define the `bind` function.
|
||||||
|
@ -265,18 +264,18 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
`getLine` is an IO action which take a world as parameter and return a couple `(String,World)`.
|
`getLine` is an IO action which takes a world as parameter and returns a couple `(String,World)`.
|
||||||
Which can be said as: `getLine` is of type `IO String`.
|
Which can be summarized as: `getLine` is of type `IO String`.
|
||||||
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
Which we also see as, an IO action which will return a String "embeded inside an IO".
|
||||||
|
|
||||||
The function `print` is also interresting.
|
The function `print` is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type `((),World)`.
|
It then returns a couple of type `((),World)`.
|
||||||
This means it changes the world state, but don't give anymore data.
|
This means it changes the state of the world, but doesn't yield anymore data.
|
||||||
|
|
||||||
This type help us simplify the type of `bind`:
|
This type helps us simplify the type of `bind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
bind :: IO a
|
bind :: IO a
|
||||||
|
@ -302,7 +301,7 @@ action2 :: a -> IO b
|
||||||
(y,w2) :: IO b
|
(y,w2) :: IO b
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Doesn't seem familiar?
|
Doesn't it seem familiar?
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -312,7 +311,7 @@ Doesn't seem familiar?
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
The idea is to hide the World argument with this function. Let's go:
|
The idea is to hide the World argument with this function. Let's go:
|
||||||
As example imagine if we wanted to simulate:
|
As an example imagine if we wanted to simulate:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
let (line1,w1) = getLine w0 in
|
let (line1,w1) = getLine w0 in
|
||||||
|
@ -327,7 +326,7 @@ Now, using the bind function:
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
As print is of type (World -> ((),World)), we know res = () (null type).
|
As print is of type (World -> ((),World)), we know res = () (null type).
|
||||||
If you didn't saw what was magic here, let's try with three lines this time.
|
If you didn't see what was magic here, let's try with three lines this time.
|
||||||
|
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
|
@ -345,8 +344,8 @@ Which is equivalent to:
|
||||||
print (line1 ++ line2)))
|
print (line1 ++ line2)))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Didn't you remark something?
|
Didn't you notice something?
|
||||||
Yes, there isn't anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is _MA_. _GIC_.
|
This is _MA_. _GIC_.
|
||||||
|
|
||||||
We can use a better notation.
|
We can use a better notation.
|
||||||
|
@ -361,7 +360,7 @@ Let's use `(>>=)` instead of `bind`.
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
Ho Ho Ho! Happy Christmas Everyone!
|
Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:
|
Haskell has made syntactical sugar for us:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
do
|
do
|
||||||
|
@ -382,8 +381,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
Note you can use `x` in `action2` and `x` and `y` in `action3`.
|
||||||
|
|
||||||
But what for line not using the `<-`?
|
But what about the lines not using the `<-`?
|
||||||
Easy another function `blindBind`:
|
Easy, another function `blindBind`:
|
||||||
|
|
||||||
<code class="haskell">
|
<code class="haskell">
|
||||||
blindBind :: IO a -> IO b -> IO b
|
blindBind :: IO a -> IO b -> IO b
|
||||||
|
@ -391,7 +390,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
I didn't simplified this definition for clarity purpose.
|
I didn't simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we'll use the `(>>)` operator.
|
Of course we can use a better notation, we'll use the `(>>)` operator.
|
||||||
|
|
||||||
And
|
And
|
||||||
|
@ -418,7 +417,6 @@ putInIO :: a -> IO a
|
||||||
putInIO x = IO (\w -> (x,w))
|
putInIO x = IO (\w -> (x,w))
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
This is the general way to put pure value inside the "IO context".
|
This is the general way to put pure values inside the "IO context".
|
||||||
The general name for `putInIO` is `return`.
|
The general name for `putInIO` is `return`.
|
||||||
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
This is quite a bad name when you learn Haskell. `return` is very different from what you might be used to.
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,6 @@ Is translated into:
|
||||||
> main = askUser >>=
|
> main = askUser >>=
|
||||||
> \list -> print $ sum list
|
> \list -> print $ sum list
|
||||||
|
|
||||||
You can compile this code to verify it continues to work.
|
You can compile this code to verify it keeps working.
|
||||||
|
|
||||||
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
Imagine what it would look like without the `(>>)` and `(>>=)`.
|
||||||
|
|
|
@ -2,13 +2,13 @@ First, let's take a look at the IO type.
|
||||||
|
|
||||||
> newtype IO a = IO (State# RealWorld -> (# State# RealWorld,a #))
|
> newtype IO a = IO (State# RealWorld -> (# State# RealWorld,a #))
|
||||||
|
|
||||||
Ho gosh! What is this notation?
|
Oh gosh! What is this notation?
|
||||||
|
|
||||||
I said it will be Haskell the hard way. It is.
|
I said it will be Haskell the hard way. It is.
|
||||||
Now make it easier.
|
Now make it easier.
|
||||||
|
|
||||||
First, we need to understand basic concepts.
|
First, we need to understand some basic concepts.
|
||||||
You can just forget about all these sharp sybols.
|
You can just forget about all these sharp symbols.
|
||||||
|
|
||||||
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ RealWorld is deeply magical.
|
||||||
It is primitive, but it is not unlifted (hence ptrArg).
|
It is primitive, but it is not unlifted (hence ptrArg).
|
||||||
We never manipulate values of type RealWorld; it's only used in the type system, to parameterise `State#`.
|
We never manipulate values of type RealWorld; it's only used in the type system, to parameterise `State#`.
|
||||||
|
|
||||||
Hu? It is a type with nothing inside it.
|
Uh? It is a type with nothing inside it.
|
||||||
No representation for it at all.
|
No representation for it at all.
|
||||||
It is just a name.
|
It is just a name.
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ It is a data with one parameter, a type of state.
|
||||||
|
|
||||||
The only purpose of the type parameter (`s`) is to keep different state threads separate.
|
The only purpose of the type parameter (`s`) is to keep different state threads separate.
|
||||||
|
|
||||||
In fact, let's try to traduce
|
In fact, let's try to translate
|
||||||
|
|
||||||
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
> newtype IO a = IO (State RealWorld -> (State RealWorld, a))
|
||||||
|
|
||||||
|
@ -46,21 +46,21 @@ of type (State RealWorld, String).
|
||||||
|
|
||||||
Which if we simplify another time can be said as:
|
Which if we simplify another time can be said as:
|
||||||
|
|
||||||
IO String is a function for a state of the world to anotherstate of the world and an String value.
|
IO String is a function which turns one state of the world into another state of the world and an String value.
|
||||||
|
|
||||||
It seems it fit nicely a function like `getLine`.
|
It seems to fit nicely with a function like `getLine`.
|
||||||
|
|
||||||
getLine can be functino in which we provide a state of the real world.
|
`getLine` can be a function to which we provide a state of the real world.
|
||||||
Then getLine do his job, then after that, it provide us a couple.
|
Then `getLine` does its job, then after this, it provides us with a couple of
|
||||||
|
values.
|
||||||
The String containing the content of the line read, and the changed world state.
|
The String containing the content of the line read, and the changed world state.
|
||||||
Changed because, when we had read something, the state of the world changed.
|
Changed because, when we had read something, the state of the world changed.
|
||||||
|
|
||||||
Congratulation to have followed the first _Hardcore Haskell IO_ level 1.
|
Congratulations for having followed the first _Hardcore Haskell IO_ level 1.
|
||||||
|
|
||||||
Now, it will be time to go to level 2.
|
Now, it is time to go to level 2.
|
||||||
|
|
||||||
To make things clearer, I will augment the verbosity of the type. And instead of writting `IO a`. I will write `World -> (World,a)`.
|
To make things clearer, I will increase the verbosity of the type. And instead of writing `IO a`. I will write `World -> (World,a)`.
|
||||||
|
|
||||||
It was a nice help for me.
|
It was a nice help for me.
|
||||||
It is often hard to remember that "IO a" is in fact a function.
|
It is often hard to remember that "IO a" is in fact a function.
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<%= blogimage("dali_reve.jpg","Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
<%= blogimage("dali_reve.jpg","Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document.") %>
|
||||||
|
|
||||||
Now the secret can be revealed: `IO` is a _monad_.
|
Now the secret can be revealed: `IO` is a _monad_.
|
||||||
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
Being a monad means you have access to some syntactical sugar with the `do` notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.
|
But mainly, you have access to a coding pattern which will ease the flow of your code.
|
||||||
|
|
||||||
> **Important remarks**:
|
> **Important remarks**:
|
||||||
>
|
>
|
||||||
|
@ -36,13 +36,13 @@ class Monad m where
|
||||||
>
|
>
|
||||||
> - the keyword `class` is not your friend.
|
> - the keyword `class` is not your friend.
|
||||||
> A Haskell class is _not_ a class like in object model.
|
> A Haskell class is _not_ a class like in object model.
|
||||||
> A Haskell class has a lot similarities with Java interfaces.
|
> A Haskell class has a lot of similarities with Java interfaces.
|
||||||
> A better word should have been `typeclass`.
|
> A better word should have been `typeclass`.
|
||||||
> That means a set of types.
|
> That means a set of types.
|
||||||
> For a type to belong to a class, all function of the class must be provided for this type.
|
> For a type to belong to a class, all functions of the class must be provided for this type.
|
||||||
> - In this particular example of type class, the type `m` must be a type that take an argument.
|
> - In this particular example of type class, the type `m` must be a type that takes an argument.
|
||||||
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
> for example `IO a`, but also `Maybe a`, `[a]`, etc...
|
||||||
> - To be a useful monad, your function must obey some rule.
|
> - To be a useful monad, your function must obey some rules.
|
||||||
> If your construction does not obey these rules strange things might happens:
|
> If your construction does not obey these rules strange things might happens:
|
||||||
>
|
>
|
||||||
> ~~~
|
> ~~~
|
||||||
|
@ -53,13 +53,13 @@ class Monad m where
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
There exists a lot of different type that are instance of `Monad`.
|
There are a lot of different types that are instance of `Monad`.
|
||||||
One of the easiest to describe is `Maybe`.
|
One of the easiest to describe is `Maybe`.
|
||||||
If you have a sequence of `Maybe` values, you could use monad to manipulate them.
|
If you have a sequence of `Maybe` values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep `if..then..else..` constructions.
|
It is particularly useful to remove very deep `if..then..else..` constructions.
|
||||||
|
|
||||||
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.
|
if you can afford to follow a list of operations without being negative.
|
||||||
|
|
||||||
> deposit value account = account + value
|
> deposit value account = account + value
|
||||||
> withdraw value account = account - value
|
> withdraw value account = account - value
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Now, let's make it better using Maybe and the fact it is a Monad
|
Now, let's make it better using Maybe and the fact that it is a Monad
|
||||||
|
|
||||||
> deposit :: (Num a) => a -> a -> Maybe a
|
> deposit :: (Num a) => a -> a -> Maybe a
|
||||||
> deposit value account = Just (account + value)
|
> deposit value account = Just (account + value)
|
||||||
|
|
|
@ -21,7 +21,7 @@ Not bad, but we can make it even better:
|
||||||
> print $ eligible 300 -- Just True
|
> print $ eligible 300 -- Just True
|
||||||
> print $ eligible 299 -- Nothing
|
> print $ eligible 299 -- Nothing
|
||||||
|
|
||||||
We have proved Monad are nice to make our code more elegant.
|
We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for `Maybe` can be used
|
Note this idea of code organization, in particular for `Maybe` can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.
|
In fact, this is the kind of construction we make naturally.
|
||||||
|
@ -30,7 +30,7 @@ In fact, this is the kind of construction we make naturally.
|
||||||
>
|
>
|
||||||
> The first element in the sequence being evaluated to `Nothing` will stop
|
> The first element in the sequence being evaluated to `Nothing` will stop
|
||||||
> the complete evaluation.
|
> the complete evaluation.
|
||||||
> That means, you don't execute all lines.
|
> This means you don't execute all lines.
|
||||||
> You have this for free, thanks to laziness.
|
> You have this for free, thanks to laziness.
|
||||||
|
|
||||||
The `Maybe` monad proved to be useful while being a very simple example.
|
The `Maybe` monad proved to be useful while being a very simple example.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
<%= blogimage("golconde.jpg","Golconde de Magritte") %>
|
||||||
|
|
||||||
The list monad help us to simulate non deterministic computation.
|
The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:
|
Here we go:
|
||||||
|
|
||||||
> import Control.Monad (guard)
|
> import Control.Monad (guard)
|
||||||
|
@ -34,8 +34,8 @@ For the list monad, there is also a syntactical sugar:
|
||||||
> z <- allCases,
|
> z <- allCases,
|
||||||
> 4*x + 2*y < z ]
|
> 4*x + 2*y < z ]
|
||||||
|
|
||||||
I won't list all the monads, but there is a lot of monads.
|
I won't list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for:
|
In particular, monad are very useful for:
|
||||||
|
|
||||||
- IO,
|
- IO,
|
||||||
|
@ -48,4 +48,6 @@ In particular, monad are very useful for:
|
||||||
If you have followed me until here, then you've done it!
|
If you have followed me until here, then you've done it!
|
||||||
You know monads[^03021301]!
|
You know monads[^03021301]!
|
||||||
|
|
||||||
[^03021301]: Well, you'll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.
|
[^03021301]: Well, you'll certainly need to practice a bit to get used to them
|
||||||
|
and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
In the section [Infinite Structures](#infinite-structures) we saw some simple construction.
|
In the section [Infinite Structures](#infinite-structures) we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:
|
||||||
|
|
||||||
1. no duplicate node value
|
1. no duplicate node value
|
||||||
2. well ordered tree
|
2. well ordered tree
|
||||||
|
|
||||||
In this section we will try to keep the first property.
|
In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we'll discuss on how to
|
Concerning the second one, we must relax it but we'll discuss how to
|
||||||
keep it as much as possible.
|
keep it as much as possible.
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -64,7 +65,7 @@ Our first step is to create some pseudo-random number list:
|
||||||
|
|
||||||
> shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
> shuffle = map (\x -> (x*3123) `mod` 4331) [1..]
|
||||||
|
|
||||||
Just as reminder here are the definition of `treeFromList`
|
Just as a reminder, here is the definition of `treeFromList`
|
||||||
|
|
||||||
> treeFromList :: (Ord a) => [a] -> BinTree a
|
> treeFromList :: (Ord a) => [a] -> BinTree a
|
||||||
> treeFromList [] = Empty
|
> treeFromList [] = Empty
|
||||||
|
@ -122,13 +123,13 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</code>
|
</code>
|
||||||
|
|
||||||
will loop forever.
|
will loop forever.
|
||||||
Simply because, it will try to access the head of `filter (<1) [2..]`.
|
Simply because it will try to access the head of `filter (<1) [2..]`.
|
||||||
But filter is not smart enought to understand that the result is the empty list.
|
But `filter` is not smart enought to understand that the result is the empty list.
|
||||||
|
|
||||||
Nonetheless, it is still a very cool example of what non strict program has to offer.
|
Nonetheless, it is still a very cool example of what non strict programs have to offer.
|
||||||
|
|
||||||
Left as an exercise to the reader:
|
Left as an exercise to the reader:
|
||||||
|
|
||||||
- Could you prove that there exists some number `n` such that `treeTakeDepth n (treeFromList shuffle)` will enter in an infinite loop.
|
- Prove the existence of a number `n` so that `treeTakeDepth n (treeFromList shuffle)` will enter an infinite loop.
|
||||||
- Find an upper bound for `n`.
|
- Find an upper bound for `n`.
|
||||||
- Prove there is no `shuffle` list such that, for any depth, the program ends.
|
- Prove there is no `shuffle` list so that, for any depth, the program ends.
|
||||||
|
|
|
@ -2243,12 +2243,13 @@ main = <span class="Keyword">do</span>
|
||||||
|
|
||||||
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
<h2 id="hell-difficulty-part">Hell Difficulty Part</h2>
|
||||||
|
|
||||||
<p>Congratulation to get so far!
|
<p>Congratulations for getting so far!
|
||||||
Now, some of the really hardcore stuff could start.</p>
|
Now, some of the really hardcore stuff can start.</p>
|
||||||
|
|
||||||
<p>If you are like me, you should get the functional style.
|
<p>If you are like me, you should get the functional style.
|
||||||
You should also understand a bit more the advantages of laziness by default.
|
You should also understand a bit more the advantages of laziness by default.
|
||||||
But you also don’t really understand were to start to make a real program.
|
But you also don’t really understand where to start in order to make a real
|
||||||
|
program.
|
||||||
And in particular:</p>
|
And in particular:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -2256,7 +2257,7 @@ And in particular:</p>
|
||||||
<li>Why is there a strange imperative-like notation for dealing with IO?</li>
|
<li>Why is there a strange imperative-like notation for dealing with IO?</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Be prepared, answer might be difficult to get.
|
<p>Be prepared, the answers might be complex.
|
||||||
But they all be very rewarding.</p>
|
But they all be very rewarding.</p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
@ -2269,7 +2270,7 @@ But they all be very rewarding.</p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span></p>
|
<p><span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span></p>
|
||||||
|
|
||||||
<p>A typical function doing <code>IO</code> look a lot like an imperative language:</p>
|
<p>A typical function doing <code>IO</code> looks a lot like an imperative program:</p>
|
||||||
|
|
||||||
<pre><code>f :: IO a
|
<pre><code>f :: IO a
|
||||||
f = do
|
f = do
|
||||||
|
@ -2291,17 +2292,17 @@ in this example:
|
||||||
<li><code>x :: b</code>, <code>y :: c</code></li>
|
<li><code>x :: b</code>, <code>y :: c</code></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Few objects have the type <code>IO a</code>, this should help you to choose.
|
<li>Few objects have the type <code>IO a</code>, this should help you choose.
|
||||||
In particular you cannot use pure function directly here.
|
In particular you cannot use pure functions directly here.
|
||||||
To use pure function you could do <code>action2 (purefunction x)</code> for example.</li>
|
To use pure functions you could do <code>action2 (purefunction x)</code> for example.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>In this section, I will explain how to use IO, not how they work.
|
<p>In this section, I will explain how to use IO, not how it works.
|
||||||
You’ll see how Haskell separate pure from impure part of the program.</p>
|
You’ll see how Haskell separates the pure from the impure parts of the program.</p>
|
||||||
|
|
||||||
<p>Don’t stop because you’re trying to understand the details of the syntax.
|
<p>Don’t stop because you’re trying to understand the details of the syntax.
|
||||||
Answer will come in the next section.</p>
|
Answers will come in the next section.</p>
|
||||||
|
|
||||||
<p>What to achieve?</p>
|
<p>What to achieve?</p>
|
||||||
|
|
||||||
|
@ -2329,7 +2330,7 @@ getLine :: IO String
|
||||||
print :: Show a => a -> IO ()
|
print :: Show a => a -> IO ()
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Or more interestingly, we remark each expression in the <code>do</code> block has a type of <code>IO a</code>.</p>
|
<p>Or more interestingly, we note that each expression in the <code>do</code> block has a type of <code>IO a</code>.</p>
|
||||||
|
|
||||||
<pre>
|
<pre>
|
||||||
main = do
|
main = do
|
||||||
|
@ -2338,7 +2339,7 @@ main = do
|
||||||
print Something :: <span class="high">IO ()</span>
|
print Something :: <span class="high">IO ()</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>We should also remark the effect of the <code><-</code> symbol.</p>
|
<p>We should also pay attention to the effect of the <code><-</code> symbol.</p>
|
||||||
|
|
||||||
<pre><code>do
|
<pre><code>do
|
||||||
x <- something
|
x <- something
|
||||||
|
@ -2346,8 +2347,8 @@ main = do
|
||||||
|
|
||||||
<p>If <code>something :: IO a</code> then <code>x :: a</code>.</p>
|
<p>If <code>something :: IO a</code> then <code>x :: a</code>.</p>
|
||||||
|
|
||||||
<p>Another important remark to use <code>IO</code>.
|
<p>Another important note about using <code>IO</code>.
|
||||||
All line in a do block must have one of the two forms:</p>
|
All lines in a do block must be of one of the two forms:</p>
|
||||||
|
|
||||||
<pre><code>action1 :: IO a
|
<pre><code>action1 :: IO a
|
||||||
-- in this case, generally a = ()
|
-- in this case, generally a = ()
|
||||||
|
@ -2360,15 +2361,15 @@ All line in a do block must have one of the two forms:</p>
|
||||||
-- value :: b
|
-- value :: b
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>These two kind of line will correspond to two different way of sequencing actions.
|
<p>These two kinds of line will correspond to two different ways of sequencing actions.
|
||||||
The meaning of this sentence should be clearer at the end of the next section.</p>
|
The meaning of this sentence should be clearer by the end of the next section.</p>
|
||||||
|
|
||||||
<p><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a></p>
|
<p><a href="code/03_Hell/01_IO/01_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>01_progressive_io_example.lhs</strong> </a></p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a></p>
|
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong></a></p>
|
||||||
|
|
||||||
<p>Now let’s see how this behave.
|
<p>Now let’s see how this program behaves.
|
||||||
For example, what occur if the user enter something strange?
|
For example, what occur if the user enter something strange?
|
||||||
Let’s try:</p>
|
Let’s try:</p>
|
||||||
|
|
||||||
|
@ -2381,7 +2382,7 @@ Let’s try:</p>
|
||||||
<p>Argh! An evil error message and a crash!
|
<p>Argh! An evil error message and a crash!
|
||||||
The first evolution will be to answer with a more friendly message.</p>
|
The first evolution will be to answer with a more friendly message.</p>
|
||||||
|
|
||||||
<p>For this, we must detect, something went wrong.
|
<p>In order to do this, we must detect that something went wrong.
|
||||||
Here is one way to do this.
|
Here is one way to do this.
|
||||||
Use the type <code>Maybe</code>.
|
Use the type <code>Maybe</code>.
|
||||||
It is a very common type in Haskell.</p>
|
It is a very common type in Haskell.</p>
|
||||||
|
@ -2391,7 +2392,7 @@ It is a very common type in Haskell.</p>
|
||||||
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
<span class="Keyword">import</span> <span class="Constant">Data</span>.<span class="Constant">Maybe</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>What is this thing? Maybe is a type which takes one parameter.
|
<p>What is this thing? <code>Maybe</code> is a type which takes one parameter.
|
||||||
Its definition is:</p>
|
Its definition is:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -2439,35 +2440,36 @@ main = <span class="Keyword">do</span>
|
||||||
<span class="Constant">Nothing</span> -> <span class="Entity">error</span> <span class="String"><span class="String">"</span>Bad format. Good Bye.<span class="String">"</span></span>
|
<span class="Constant">Nothing</span> -> <span class="Entity">error</span> <span class="String"><span class="String">"</span>Bad format. Good Bye.<span class="String">"</span></span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>In case of error, we prompt a nice error message.</p>
|
<p>In case of error, we display a nice error message.</p>
|
||||||
|
|
||||||
<p>Remark the type of each expression in the main’s do block remains of the form <code>IO a</code>.
|
<p>Note that the type of each expression in the main’s do block remains of the form <code>IO a</code>.
|
||||||
The only strange construction is <code>error</code>.
|
The only strange construction is <code>error</code>.
|
||||||
I’ll say <code>error msg</code> will simply take the needed type (here <code>IO ()</code>).</p>
|
I’ll say <code>error msg</code> will simply take the needed type (here <code>IO ()</code>).</p>
|
||||||
|
|
||||||
<p>One very important thing to note is the type of all the defined function.
|
<p>One very important thing to note is the type of all the functions defined so far.
|
||||||
There is only one function which contains <code>IO</code> in its type: <code>main</code>.
|
There is only one function which contains <code>IO</code> in its type: <code>main</code>.
|
||||||
That means main is impure.
|
This means main is impure.
|
||||||
But main use <code>getListFromString</code> which is pure.
|
But main uses <code>getListFromString</code> which is pure.
|
||||||
It is then clear just by looking at declared types where are pure and impure functions.</p>
|
It is then clear just by looking at declared types which functions are pure and
|
||||||
|
which are impure.</p>
|
||||||
|
|
||||||
<p>Why purity matters?
|
<p>Why does purity matter?
|
||||||
I certainly forget many advantages, but the three main reason are:</p>
|
I certainly forget many advantages, but the three main reasons are:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>It is far easier to think about pure code than impure one.</li>
|
<li>It is far easier to think about pure code than impure one.</li>
|
||||||
<li>Purity protect you from all hard to reproduce bugs due to border effects.</li>
|
<li>Purity protects you from all the hard to reproduce bugs due to side effects.</li>
|
||||||
<li>You can evaluate pure functions in any order or in parallel without risk.</li>
|
<li>You can evaluate pure functions in any order or in parallel without risk.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>This is why, you should generally put as most code as possible in pure functions.</p>
|
<p>This is why you should generally put as most code as possible inside pure functions.</p>
|
||||||
|
|
||||||
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a></p>
|
<p><a href="code/03_Hell/01_IO/02_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>02_progressive_io_example.lhs</strong> </a></p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
<p><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a></p>
|
<p><a href="code/03_Hell/01_IO/03_progressive_io_example.lhs" class="cut">03_Hell/01_IO/<strong>03_progressive_io_example.lhs</strong></a></p>
|
||||||
|
|
||||||
<p>Our next evolution will be to ask the user again and again until it enters a valid answer.</p>
|
<p>Our next evolution will be to prompt the user again and again until she enters a valid answer.</p>
|
||||||
|
|
||||||
<p>We keep the first part:</p>
|
<p>We keep the first part:</p>
|
||||||
|
|
||||||
|
@ -2483,7 +2485,7 @@ maybeRead s = <span class="Keyword">case</span> <span class="Entity">reads</span
|
||||||
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
getListFromString str = maybeRead $ <span class="String"><span class="String">"</span>[<span class="String">"</span></span> ++ str ++ <span class="String"><span class="String">"</span>]<span class="String">"</span></span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>Now, we create a function which will ask the user for an integer list
|
<p>Now, we create a function which will ask the user for an list of integers
|
||||||
until the input is right.</p>
|
until the input is right.</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -2499,7 +2501,7 @@ askUser = <span class="Keyword">do</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>This function is of type <code>IO [Integer]</code>.
|
<p>This function is of type <code>IO [Integer]</code>.
|
||||||
Such a type means, that we retrieved a value of type <code>[Integer]</code> through some IO actions.
|
Such a type means that we retrieved a value of type <code>[Integer]</code> through some IO actions.
|
||||||
Some people might explain while waving their hands: </p>
|
Some people might explain while waving their hands: </p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
|
@ -2508,7 +2510,7 @@ Some people might explain while waving their hands: </p>
|
||||||
|
|
||||||
<p>If you want to understand the details behind all of this, you’ll have to read the next section.
|
<p>If you want to understand the details behind all of this, you’ll have to read the next section.
|
||||||
But sincerely, if you just want to <em>use</em> IO.
|
But sincerely, if you just want to <em>use</em> IO.
|
||||||
Just exercise a little and remember to think about the type.</p>
|
Just practice a little and remember to think about the type.</p>
|
||||||
|
|
||||||
<p>Finally our main function is quite simpler:</p>
|
<p>Finally our main function is quite simpler:</p>
|
||||||
|
|
||||||
|
@ -2521,25 +2523,25 @@ main = <span class="Keyword">do</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>We have finished with our introduction to <code>IO</code>.
|
<p>We have finished with our introduction to <code>IO</code>.
|
||||||
This was quite a fast. Here are the main things to remind:</p>
|
This was quite fast. Here are the main things to remember:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>in the <code>do</code> bloc, each expression must have the type <code>IO a</code>.
|
<li>in the <code>do</code> bloc, each expression must have the type <code>IO a</code>.
|
||||||
You are then limited in the number of expression you could use.
|
You are then limited in the number of expressions available.
|
||||||
For example, <code>getLine</code>, <code>print</code>, <code>putStrLn</code>, etc…</li>
|
For example, <code>getLine</code>, <code>print</code>, <code>putStrLn</code>, etc…</li>
|
||||||
<li>Try to externalize the pure function as much as possible. </li>
|
<li>Try to externalize the pure functions as much as possible.</li>
|
||||||
<li>the <code>IO a</code> type means: an IO <em>action</em> which return an element of type <code>a</code>.
|
<li>the <code>IO a</code> type means: an IO <em>action</em> which returns an element of type <code>a</code>.
|
||||||
<code>IO</code> represent action; under the hood, <code>IO a</code> is the type of a function.
|
<code>IO</code> represents actions; under the hood, <code>IO a</code> is the type of a function.
|
||||||
Read the next section if you are curious.</li>
|
Read the next section if you are curious.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>If you exercise a bit, you should be able to <em>use</em> <code>IO</code>.</p>
|
<p>If you practice a bit, you should be able to <em>use</em> <code>IO</code>.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><em>Exercises</em>:</p>
|
<p><em>Exercises</em>:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Make a program that sum all its argument. Hint: use the function <code>getArgs</code>.</li>
|
<li>Make a program that sums all of its arguments. Hint: use the function <code>getArgs</code>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -2552,14 +2554,14 @@ Read the next section if you are curious.</li>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>Here is a <span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span> for this section.</p>
|
<p>Here is a <span class="sc"><abbr title="Too long; didn't read">tl;dr</abbr>: </span> for this section.</p>
|
||||||
|
|
||||||
<p>To separate pure from impure part,
|
<p>To separate pure and impure parts,
|
||||||
the main is defined as a function
|
<code>main</code> is defined as a function
|
||||||
which modify the state of the world</p>
|
which modifies the state of the world</p>
|
||||||
|
|
||||||
<pre><code>main :: World -> World
|
<pre><code>main :: World -> World
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>A function is granted to have side effect only if it gets this value.
|
<p>A function is guaranteed to have side effects only if it has this type.
|
||||||
But look at a typical main function:</p>
|
But look at a typical main function:</p>
|
||||||
|
|
||||||
<pre><code>main w0 =
|
<pre><code>main w0 =
|
||||||
|
@ -2570,16 +2572,16 @@ But look at a typical main function:</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>We have a lot of temporary elements (here <code>w1</code>, <code>w2</code> and <code>w3</code>)
|
<p>We have a lot of temporary elements (here <code>w1</code>, <code>w2</code> and <code>w3</code>)
|
||||||
which must be passed to the next action.</p>
|
which must be passed on to the next action.</p>
|
||||||
|
|
||||||
<p>We create a function <code>bind</code> or <code>(>>=)</code>.
|
<p>We create a function <code>bind</code> or <code>(>>=)</code>.
|
||||||
With <code>bind</code> we need no more temporary name.</p>
|
With <code>bind</code> we don’t need temporary names anymore.</p>
|
||||||
|
|
||||||
<pre><code>main =
|
<pre><code>main =
|
||||||
action1 >>= action2 >>= action3 >>= action4
|
action1 >>= action2 >>= action3 >>= action4
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
<p>Bonus: Haskell has a syntactical sugar for us:</p>
|
<p>Bonus: Haskell has syntactical sugar for us:</p>
|
||||||
|
|
||||||
<pre><code>main = do
|
<pre><code>main = do
|
||||||
v1 <- action1
|
v1 <- action1
|
||||||
|
@ -2589,11 +2591,11 @@ With <code>bind</code> we need no more temporary name.</p>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
<p>Why did we used some strange syntax, and what exactly is this <code>IO</code> type.
|
<p>Why did we use this strange syntax, and what exactly is this <code>IO</code> type?
|
||||||
It looks a bit like magic.</p>
|
It looks a bit like magic.</p>
|
||||||
|
|
||||||
<p>For now let’s just forget about all the pure part of our program, and focus
|
<p>For now let’s just forget all about the pure parts of our program, and focus
|
||||||
on the impure part:</p>
|
on the impure parts:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
<span class="Entity">askUser</span> :: <span class="Constant">IO</span> [<span class="Constant">Integer</span>]
|
||||||
|
@ -2612,31 +2614,31 @@ main = <span class="Keyword">do</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>First remark; it looks like an imperative structure.
|
<p>First remark; it looks like an imperative structure.
|
||||||
Haskell is powerful enough to make some pure code to look imperative.
|
Haskell is powerful enough to make impure code look imperative.
|
||||||
For example, if you wish you could create a <code>while</code> in Haskell.
|
For example, if you wish you could create a <code>while</code> in Haskell.
|
||||||
In fact, for dealing with <code>IO</code>, imperative style is generally more appropriate.</p>
|
In fact, for dealing with <code>IO</code>, imperative style is generally more appropriate.</p>
|
||||||
|
|
||||||
<p>But, you should had remarked the notation is a bit unusual.
|
<p>But you should had noticed the notation is a bit unusual.
|
||||||
Here is why, in detail.</p>
|
Here is why, in detail.</p>
|
||||||
|
|
||||||
<p>In an impure language, the state of the world can be seen as a huge hidden global variable.
|
<p>In an impure language, the state of the world can be seen as a huge hidden global variable.
|
||||||
This hidden variable is accessible by all function of your language.
|
This hidden variable is accessible by all functions of your language.
|
||||||
For example, you can read and write a file in any function.
|
For example, you can read and write a file in any function.
|
||||||
The fact a file exists or not, can be seen as different state of the world.</p>
|
The fact that a file exists or not can be seen as different states of the world.</p>
|
||||||
|
|
||||||
<p>For Haskell this state is not hidden.
|
<p>For Haskell this state is not hidden.
|
||||||
It is explicitly said <code>main</code> is a function that <em>potentially</em> change the state of the world.
|
It is explicitly said <code>main</code> is a function that <em>potentially</em> changes the state of the world.
|
||||||
It’s type is then something like:</p>
|
Its type is then something like:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">main</span> :: <span class="Constant">World</span> -> <span class="Constant">World</span>
|
<span class="Entity">main</span> :: <span class="Constant">World</span> -> <span class="Constant">World</span>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Not all function could have access to this variable.
|
<p>Not all functions may have access to this variable.
|
||||||
Those who have access to this variable can potentially be impure.
|
Those which have access to this variable are impure.
|
||||||
Functions whose the world variable isn’t provided to should be pure<sup id="fnref:032001"><a href="#fn:032001" rel="footnote">6</a></sup>.</p>
|
Functions to which the world variable isn’t provided are pure<sup id="fnref:032001"><a href="#fn:032001" rel="footnote">6</a></sup>.</p>
|
||||||
|
|
||||||
<p>Haskell consider the state of the world is an input variable for <code>main</code>.
|
<p>Haskell considers the state of the world as an input variable to <code>main</code>.
|
||||||
But the real type of main is closer to this one<sup id="fnref:032002"><a href="#fn:032002" rel="footnote">7</a></sup>:</p>
|
But the real type of main is closer to this one<sup id="fnref:032002"><a href="#fn:032002" rel="footnote">7</a></sup>:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -2655,17 +2657,17 @@ main w0 =
|
||||||
x
|
x
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>First, we remark, that all function which have side effect must have the type:</p>
|
<p>First, we note that all functions which have side effects must have the type:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Constant">World</span> -> (a,<span class="Constant">World</span>)
|
<span class="Constant">World</span> -> (a,<span class="Constant">World</span>)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Where <code>a</code> is the type of result.
|
<p>Where <code>a</code> is the type of the result.
|
||||||
For example, a <code>getChar</code> function should have the type <code>World -> (Char,World)</code>.</p>
|
For example, a <code>getChar</code> function should have the type <code>World -> (Char,World)</code>.</p>
|
||||||
|
|
||||||
<p>Another thing to remark is the trick to fix the order of evaluation.
|
<p>Another thing to note is the trick to fix the order of evaluation.
|
||||||
In Haskell to evaluate <code>f a b</code>, you generally have many choices: </p>
|
In Haskell, in order to evaluate <code>f a b</code>, you have many choices:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>first eval <code>a</code> then <code>b</code> then <code>f a b</code></li>
|
<li>first eval <code>a</code> then <code>b</code> then <code>f a b</code></li>
|
||||||
|
@ -2690,7 +2692,7 @@ Under the hood, <code>print</code> will evaluate as:</p>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>Now, if you look at the style of the main function, it is clearly awkward.
|
<p>Now, if you look at the style of the main function, it is clearly awkward.
|
||||||
Let’s try to make the same to the askUser function:</p>
|
Let’s try to do the same to the askUser function:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">askUser</span> :: <span class="Constant">World</span> -> ([<span class="Constant">Integer</span>],<span class="Constant">World</span>)
|
<span class="Entity">askUser</span> :: <span class="Constant">World</span> -> ([<span class="Constant">Integer</span>],<span class="Constant">World</span>)
|
||||||
|
@ -2725,9 +2727,9 @@ askUser w0 =
|
||||||
<p>This is similar, but awkward.
|
<p>This is similar, but awkward.
|
||||||
Look at all these temporary <code>w?</code> names.</p>
|
Look at all these temporary <code>w?</code> names.</p>
|
||||||
|
|
||||||
<p>The lesson, is, naive IO implementation in Pure functional language is awkward!</p>
|
<p>The lesson, is, naive IO implementation in Pure functional languages is awkward!</p>
|
||||||
|
|
||||||
<p>Fortunately, some have found a better way to handle this problem.
|
<p>Fortunately, there is a better way to handle this problem.
|
||||||
We see a pattern.
|
We see a pattern.
|
||||||
Each line is of the form:</p>
|
Each line is of the form:</p>
|
||||||
|
|
||||||
|
@ -2743,8 +2745,7 @@ Each function <code>f</code> must have a type similar to:</p>
|
||||||
<span class="Entity">f</span> :: <span class="Constant">World</span> -> (<span class="Variable">a,World</span>)
|
<span class="Entity">f</span> :: <span class="Constant">World</span> -> (<span class="Variable">a,World</span>)
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Not only this, but we can also remark we use them always
|
<p>Not only this, but we can also note that we always follow the same usage pattern:</p>
|
||||||
with the following general pattern:</p>
|
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">let</span> (y,w1) = action1 w0 <span class="Keyword">in</span>
|
<span class="Keyword">let</span> (y,w1) = action1 w0 <span class="Keyword">in</span>
|
||||||
|
@ -2753,7 +2754,7 @@ with the following general pattern:</p>
|
||||||
...
|
...
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Each action can take 0 to some parameters.
|
<p>Each action can take from 0 to n parameters.
|
||||||
And in particular, each action can take a parameter from the result of a line above.</p>
|
And in particular, each action can take a parameter from the result of a line above.</p>
|
||||||
|
|
||||||
<p>For example, we could also have:</p>
|
<p>For example, we could also have:</p>
|
||||||
|
@ -2768,7 +2769,7 @@ And in particular, each action can take a parameter from the result of a line ab
|
||||||
<p>And of course <code>actionN w :: (World) -> (a,World)</code>.</p>
|
<p>And of course <code>actionN w :: (World) -> (a,World)</code>.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>IMPORTANT, there are only two important pattern for us:</p>
|
<p>IMPORTANT, there are only two important patterns to consider:</p>
|
||||||
|
|
||||||
<pre><code>let (x,w1) = action1 w0 in
|
<pre><code>let (x,w1) = action1 w0 in
|
||||||
let (y,w2) = action2 x w1 in
|
let (y,w2) = action2 x w1 in
|
||||||
|
@ -2783,7 +2784,7 @@ let (y,w2) = action2 w1 in
|
||||||
|
|
||||||
<p><img alt="Jocker pencil trick" src="/Scratch/img/blog/Haskell-the-Hard-Way/jocker_pencil_trick.jpg" class="left" /></p>
|
<p><img alt="Jocker pencil trick" src="/Scratch/img/blog/Haskell-the-Hard-Way/jocker_pencil_trick.jpg" class="left" /></p>
|
||||||
|
|
||||||
<p>Now, we will make a magic trick.
|
<p>Now, we will do a magic trick.
|
||||||
We will make the temporary world symbol “disappear”.
|
We will make the temporary world symbol “disappear”.
|
||||||
We will <code>bind</code> the two lines.
|
We will <code>bind</code> the two lines.
|
||||||
Let’s define the <code>bind</code> function.
|
Let’s define the <code>bind</code> function.
|
||||||
|
@ -2809,18 +2810,18 @@ Now let’s rename it for clarity:</p>
|
||||||
<span class="Entity">print</span> :: <span class="Constant">Show</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">IO</span> ()
|
<span class="Entity">print</span> :: <span class="Constant">Show</span> <span class="Variable">a</span> => <span class="Variable">a</span> -> <span class="Constant">IO</span> ()
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p><code>getLine</code> is an IO action which take a world as parameter and return a couple <code>(String,World)</code>.
|
<p><code>getLine</code> is an IO action which takes a world as parameter and returns a couple <code>(String,World)</code>.
|
||||||
Which can be said as: <code>getLine</code> is of type <code>IO String</code>.
|
Which can be summarized as: <code>getLine</code> is of type <code>IO String</code>.
|
||||||
Which we also see as, an IO action which will return a String “embeded inside an IO”.</p>
|
Which we also see as, an IO action which will return a String “embeded inside an IO”.</p>
|
||||||
|
|
||||||
<p>The function <code>print</code> is also interresting.
|
<p>The function <code>print</code> is also interesting.
|
||||||
It takes on argument which can be shown.
|
It takes one argument which can be shown.
|
||||||
In fact it takes two arguments.
|
In fact it takes two arguments.
|
||||||
The first is the value to print and the other is the state of world.
|
The first is the value to print and the other is the state of world.
|
||||||
It then return a couple of type <code>((),World)</code>.
|
It then returns a couple of type <code>((),World)</code>.
|
||||||
This means it changes the world state, but don’t give anymore data.</p>
|
This means it changes the state of the world, but doesn’t yield anymore data.</p>
|
||||||
|
|
||||||
<p>This type help us simplify the type of <code>bind</code>:</p>
|
<p>This type helps us simplify the type of <code>bind</code>:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">bind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span>
|
<span class="Entity">bind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span>
|
||||||
|
@ -2846,7 +2847,7 @@ This means it changes the world state, but don’t give anymore data.</p>
|
||||||
(y,w2) :: <span class="Constant">IO</span> b
|
(y,w2) :: <span class="Constant">IO</span> b
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Doesn’t seem familiar?</p>
|
<p>Doesn’t it seem familiar?</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
(bind action1 action2) w0 =
|
(bind action1 action2) w0 =
|
||||||
|
@ -2856,7 +2857,7 @@ This means it changes the world state, but don’t give anymore data.</p>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>The idea is to hide the World argument with this function. Let’s go:
|
<p>The idea is to hide the World argument with this function. Let’s go:
|
||||||
As example imagine if we wanted to simulate:</p>
|
As an example imagine if we wanted to simulate:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
||||||
|
@ -2871,7 +2872,7 @@ As example imagine if we wanted to simulate:</p>
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>As print is of type (World → ((),World)), we know res = () (null type).
|
<p>As print is of type (World → ((),World)), we know res = () (null type).
|
||||||
If you didn’t saw what was magic here, let’s try with three lines this time.</p>
|
If you didn’t see what was magic here, let’s try with three lines this time.</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
<span class="Keyword">let</span> (line1,w1) = <span class="Entity">getLine</span> w0 <span class="Keyword">in</span>
|
||||||
|
@ -2888,8 +2889,8 @@ If you didn’t saw what was magic here, let’s try with three lines th
|
||||||
<span class="Entity">print</span> (line1 ++ line2)))
|
<span class="Entity">print</span> (line1 ++ line2)))
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Didn’t you remark something?
|
<p>Didn’t you notice something?
|
||||||
Yes, there isn’t anymore temporary World variable used anywhere!
|
Yes, no temporary World variables are used anywhere!
|
||||||
This is <em>MA</em>. <em>GIC</em>.</p>
|
This is <em>MA</em>. <em>GIC</em>.</p>
|
||||||
|
|
||||||
<p>We can use a better notation.
|
<p>We can use a better notation.
|
||||||
|
@ -2904,7 +2905,7 @@ Let’s use <code>(>>=)</code> instead of <code>bind</code>.
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>Ho Ho Ho! Happy Christmas Everyone!
|
<p>Ho Ho Ho! Happy Christmas Everyone!
|
||||||
Haskell has made a syntactical sugar for us:</p>
|
Haskell has made syntactical sugar for us:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Keyword">do</span>
|
<span class="Keyword">do</span>
|
||||||
|
@ -2925,8 +2926,8 @@ action3 >>= \z ->
|
||||||
|
|
||||||
<p>Note you can use <code>x</code> in <code>action2</code> and <code>x</code> and <code>y</code> in <code>action3</code>.</p>
|
<p>Note you can use <code>x</code> in <code>action2</code> and <code>x</code> and <code>y</code> in <code>action3</code>.</p>
|
||||||
|
|
||||||
<p>But what for line not using the <code><-</code>?
|
<p>But what about the lines not using the <code><-</code>?
|
||||||
Easy another function <code>blindBind</code>:</p>
|
Easy, another function <code>blindBind</code>:</p>
|
||||||
|
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
<span class="Entity">blindBind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">b</span> -> <span class="Constant">IO</span> <span class="Variable">b</span>
|
<span class="Entity">blindBind</span> :: <span class="Constant">IO</span> <span class="Variable">a</span> -> <span class="Constant">IO</span> <span class="Variable">b</span> -> <span class="Constant">IO</span> <span class="Variable">b</span>
|
||||||
|
@ -2934,7 +2935,7 @@ blindBind action1 action2 w0 =
|
||||||
bind action (\_ -> action2) w0
|
bind action (\_ -> action2) w0
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>I didn’t simplified this definition for clarity purpose.
|
<p>I didn’t simplify this definition for clarity purpose.
|
||||||
Of course we can use a better notation, we’ll use the <code>(>>)</code> operator.</p>
|
Of course we can use a better notation, we’ll use the <code>(>>)</code> operator.</p>
|
||||||
|
|
||||||
<p>And</p>
|
<p>And</p>
|
||||||
|
@ -2961,7 +2962,7 @@ action3
|
||||||
putInIO x = <span class="Constant">IO</span> (\w -> (x,w))
|
putInIO x = <span class="Constant">IO</span> (\w -> (x,w))
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>This is the general way to put pure value inside the “IO context”.
|
<p>This is the general way to put pure values inside the “IO context”.
|
||||||
The general name for <code>putInIO</code> is <code>return</code>.
|
The general name for <code>putInIO</code> is <code>return</code>.
|
||||||
This is quite a bad name when you learn Haskell. <code>return</code> is very different from what you might be used to. </p>
|
This is quite a bad name when you learn Haskell. <code>return</code> is very different from what you might be used to. </p>
|
||||||
|
|
||||||
|
@ -3013,7 +3014,7 @@ main = askUser >>=
|
||||||
\list -> <span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
\list -> <span class="Entity">print</span> $ <span class="Entity">sum</span> list
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>You can compile this code to verify it continues to work.</p>
|
<p>You can compile this code to verify it keeps working.</p>
|
||||||
|
|
||||||
<p>Imagine what it would look like without the <code>(>>)</code> and <code>(>>=)</code>.</p>
|
<p>Imagine what it would look like without the <code>(>>)</code> and <code>(>>=)</code>.</p>
|
||||||
|
|
||||||
|
@ -3024,11 +3025,11 @@ main = askUser >>=
|
||||||
|
|
||||||
<h3 id="monads">Monads</h3>
|
<h3 id="monads">Monads</h3>
|
||||||
|
|
||||||
<p><img alt="Dali, reve. It represent a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itsleft out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document." src="/Scratch/img/blog/Haskell-the-Hard-Way/dali_reve.jpg" /></p>
|
<p><img alt="Dali, reve. It represents a weapon out of the mouth of a tiger, itself out of the mouth of another tiger, itself out of the mouth of a fish itself out of a grenade. I could have choosen a picture of the Human centipede as it is a very good representation of what a monad really is. But just to thing about it, I find this disgusting and that wasn't the purpose of this document." src="/Scratch/img/blog/Haskell-the-Hard-Way/dali_reve.jpg" /></p>
|
||||||
|
|
||||||
<p>Now the secret can be revealed: <code>IO</code> is a <em>monad</em>.
|
<p>Now the secret can be revealed: <code>IO</code> is a <em>monad</em>.
|
||||||
Being a monad means you have access to some syntactical sugar with the <code>do</code> notation.
|
Being a monad means you have access to some syntactical sugar with the <code>do</code> notation.
|
||||||
But mainly, you have access to some coding pattern which will ease the flow of your code.</p>
|
But mainly, you have access to a coding pattern which will ease the flow of your code.</p>
|
||||||
|
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p><strong>Important remarks</strong>:</p>
|
<p><strong>Important remarks</strong>:</p>
|
||||||
|
@ -3065,14 +3066,14 @@ Here is how the type class <code>Monad</code> is declared (mostly):</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>the keyword <code>class</code> is not your friend.
|
<li>the keyword <code>class</code> is not your friend.
|
||||||
A Haskell class is <em>not</em> a class like in object model.
|
A Haskell class is <em>not</em> a class like in object model.
|
||||||
A Haskell class has a lot similarities with Java interfaces.
|
A Haskell class has a lot of similarities with Java interfaces.
|
||||||
A better word should have been <code>typeclass</code>.
|
A better word should have been <code>typeclass</code>.
|
||||||
That means a set of types.
|
That means a set of types.
|
||||||
For a type to belong to a class, all function of the class must be provided for this type.</li>
|
For a type to belong to a class, all functions of the class must be provided for this type.</li>
|
||||||
<li>In this particular example of type class, the type <code>m</code> must be a type that take an argument.
|
<li>In this particular example of type class, the type <code>m</code> must be a type that takes an argument.
|
||||||
for example <code>IO a</code>, but also <code>Maybe a</code>, <code>[a]</code>, etc…</li>
|
for example <code>IO a</code>, but also <code>Maybe a</code>, <code>[a]</code>, etc…</li>
|
||||||
<li>
|
<li>
|
||||||
<p>To be a useful monad, your function must obey some rule.
|
<p>To be a useful monad, your function must obey some rules.
|
||||||
If your construction does not obey these rules strange things might happens:</p>
|
If your construction does not obey these rules strange things might happens:</p>
|
||||||
|
|
||||||
<pre><code>return a >>= k == k a
|
<pre><code>return a >>= k == k a
|
||||||
|
@ -3085,13 +3086,13 @@ m >>= (\x -> k x >>= h) == (m >>= k) >>= h
|
||||||
|
|
||||||
<h4 id="maybe-monad">Maybe is a monad</h4>
|
<h4 id="maybe-monad">Maybe is a monad</h4>
|
||||||
|
|
||||||
<p>There exists a lot of different type that are instance of <code>Monad</code>.
|
<p>There are a lot of different types that are instance of <code>Monad</code>.
|
||||||
One of the easiest to describe is <code>Maybe</code>.
|
One of the easiest to describe is <code>Maybe</code>.
|
||||||
If you have a sequence of <code>Maybe</code> values, you could use monad to manipulate them.
|
If you have a sequence of <code>Maybe</code> values, you can use monads to manipulate them.
|
||||||
It is particularly useful to remove very deep <code>if..then..else..</code> constructions.</p>
|
It is particularly useful to remove very deep <code>if..then..else..</code> constructions.</p>
|
||||||
|
|
||||||
<p>Imagine a complex bank operation. You are eligible to gain about 700€ only
|
<p>Imagine a complex bank operation. You are eligible to gain about 700€ only
|
||||||
if you can afford to follow a list of operation without being negative.</p>
|
if you can afford to follow a list of operations without being negative.</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -3132,7 +3133,7 @@ main = <span class="Keyword">do</span>
|
||||||
<hr />
|
<hr />
|
||||||
<p><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a></p>
|
<p><a href="code/03_Hell/02_Monads/11_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>11_Monads.lhs</strong></a></p>
|
||||||
|
|
||||||
<p>Now, let’s make it better using Maybe and the fact it is a Monad</p>
|
<p>Now, let’s make it better using Maybe and the fact that it is a Monad</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -3189,7 +3190,7 @@ main = <span class="Keyword">do</span>
|
||||||
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> Nothing</span>
|
<span class="Entity">print</span> $ eligible 299 <span class="Comment"><span class="Comment">--</span> Nothing</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>We have proved Monad are nice to make our code more elegant.
|
<p>We have proven that Monads are a good way to make our code more elegant.
|
||||||
Note this idea of code organization, in particular for <code>Maybe</code> can be used
|
Note this idea of code organization, in particular for <code>Maybe</code> can be used
|
||||||
in most imperative language.
|
in most imperative language.
|
||||||
In fact, this is the kind of construction we make naturally.</p>
|
In fact, this is the kind of construction we make naturally.</p>
|
||||||
|
@ -3199,7 +3200,7 @@ In fact, this is the kind of construction we make naturally.</p>
|
||||||
|
|
||||||
<p>The first element in the sequence being evaluated to <code>Nothing</code> will stop
|
<p>The first element in the sequence being evaluated to <code>Nothing</code> will stop
|
||||||
the complete evaluation.
|
the complete evaluation.
|
||||||
That means, you don’t execute all lines.
|
This means you don’t execute all lines.
|
||||||
You have this for free, thanks to laziness.</p>
|
You have this for free, thanks to laziness.</p>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
|
@ -3216,7 +3217,7 @@ But now a cooler example, lists.</p>
|
||||||
|
|
||||||
<p><img alt="Golconde de Magritte" src="/Scratch/img/blog/Haskell-the-Hard-Way/golconde.jpg" /></p>
|
<p><img alt="Golconde de Magritte" src="/Scratch/img/blog/Haskell-the-Hard-Way/golconde.jpg" /></p>
|
||||||
|
|
||||||
<p>The list monad help us to simulate non deterministic computation.
|
<p>The list monad helps us to simulate non deterministic computations.
|
||||||
Here we go:</p>
|
Here we go:</p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
|
@ -3252,8 +3253,8 @@ main = <span class="Keyword">do</span>
|
||||||
4*x + 2*y < z ]
|
4*x + 2*y < z ]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>I won’t list all the monads, but there is a lot of monads.
|
<p>I won’t list all the monads, but there are many monads.
|
||||||
The usage of monad simplify the manipulation of some notion in pure languages.
|
Using monads simplifies the manipulation of several notions in pure languages.
|
||||||
In particular, monad are very useful for: </p>
|
In particular, monad are very useful for: </p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -3268,6 +3269,9 @@ In particular, monad are very useful for: </p>
|
||||||
<p>If you have followed me until here, then you’ve done it!
|
<p>If you have followed me until here, then you’ve done it!
|
||||||
You know monads<sup id="fnref:03021301"><a href="#fn:03021301" rel="footnote">8</a></sup>!</p>
|
You know monads<sup id="fnref:03021301"><a href="#fn:03021301" rel="footnote">8</a></sup>!</p>
|
||||||
|
|
||||||
|
<p>and to understand when you can use them and create your own. But you already
|
||||||
|
made a big step in this direction.</p>
|
||||||
|
|
||||||
<p><a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a></p>
|
<p><a href="code/03_Hell/02_Monads/13_Monads.lhs" class="cut">03_Hell/02_Monads/<strong>13_Monads.lhs</strong> </a></p>
|
||||||
|
|
||||||
<h2 id="appendix">Appendix</h2>
|
<h2 id="appendix">Appendix</h2>
|
||||||
|
@ -3280,8 +3284,9 @@ It is just here to discuss some details further.</p>
|
||||||
|
|
||||||
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
<h3 id="more-on-infinite-tree">More on Infinite Tree</h3>
|
||||||
|
|
||||||
<p>In the section <a href="#infinite-structures">Infinite Structures</a> we saw some simple construction.
|
<p>In the section <a href="#infinite-structures">Infinite Structures</a> we saw some simple
|
||||||
Unfortunately we removed two properties of our tree:</p>
|
constructions.
|
||||||
|
Unfortunately we removed two properties from our tree:</p>
|
||||||
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>no duplicate node value</li>
|
<li>no duplicate node value</li>
|
||||||
|
@ -3289,7 +3294,7 @@ Unfortunately we removed two properties of our tree:</p>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<p>In this section we will try to keep the first property.
|
<p>In this section we will try to keep the first property.
|
||||||
Concerning the second one, we must relax this one but we’ll discuss on how to
|
Concerning the second one, we must relax it but we’ll discuss how to
|
||||||
keep it as much as possible.</p>
|
keep it as much as possible.</p>
|
||||||
|
|
||||||
<div style="display:none">
|
<div style="display:none">
|
||||||
|
@ -3352,7 +3357,7 @@ This code is mostly the same as the one in the [tree section](#trees).
|
||||||
shuffle = <span class="Entity">map</span> (\x -> (x*3123) <span class="Entity"><span class="Entity">`</span>mod<span class="Entity">`</span></span> 4331) [1..]
|
shuffle = <span class="Entity">map</span> (\x -> (x*3123) <span class="Entity"><span class="Entity">`</span>mod<span class="Entity">`</span></span> 4331) [1..]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<p>Just as reminder here are the definition of <code>treeFromList</code></p>
|
<p>Just as a reminder, here is the definition of <code>treeFromList</code></p>
|
||||||
|
|
||||||
<div class="codehighlight">
|
<div class="codehighlight">
|
||||||
<pre class="twilight">
|
<pre class="twilight">
|
||||||
|
@ -3418,17 +3423,17 @@ treeTakeDepth 4 (treeFromList [1..])
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>will loop forever.
|
<p>will loop forever.
|
||||||
Simply because, it will try to access the head of <code>filter (<1) [2..]</code>.
|
Simply because it will try to access the head of <code>filter (<1) [2..]</code>.
|
||||||
But filter is not smart enought to understand that the result is the empty list.</p>
|
But <code>filter</code> is not smart enought to understand that the result is the empty list.</p>
|
||||||
|
|
||||||
<p>Nonetheless, it is still a very cool example of what non strict program has to offer.</p>
|
<p>Nonetheless, it is still a very cool example of what non strict programs have to offer.</p>
|
||||||
|
|
||||||
<p>Left as an exercise to the reader:</p>
|
<p>Left as an exercise to the reader:</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Could you prove that there exists some number <code>n</code> such that <code>treeTakeDepth n (treeFromList shuffle)</code> will enter in an infinite loop.</li>
|
<li>Prove the existence of a number <code>n</code> so that <code>treeTakeDepth n (treeFromList shuffle)</code> will enter an infinite loop.</li>
|
||||||
<li>Find an upper bound for <code>n</code>.</li>
|
<li>Find an upper bound for <code>n</code>.</li>
|
||||||
<li>Prove there is no <code>shuffle</code> list such that, for any depth, the program ends.</li>
|
<li>Prove there is no <code>shuffle</code> list so that, for any depth, the program ends.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p><a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a></p>
|
<p><a href="code/04_Appendice/01_More_on_infinite_trees/10_Infinite_Trees.lhs" class="cut">04_Appendice/01_More_on_infinite_trees/<strong>10_Infinite_Trees.lhs</strong> </a></p>
|
||||||
|
@ -3633,13 +3638,13 @@ treeFromList' (x:xs) n = <span class="Constant">Node</span> x left right
|
||||||
<p>Which itself is very similar to the javascript <code>eval</code> on a string containing JSON).<a href="#fnref:1" rel="reference">↩</a></p>
|
<p>Which itself is very similar to the javascript <code>eval</code> on a string containing JSON).<a href="#fnref:1" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="fn:032001">
|
<li id="fn:032001">
|
||||||
<p>There are some <em>unsafe</em> exception to this rule. But you shouldn’t see such usage on a real application except might be for some debugging purpose.<a href="#fnref:032001" rel="reference">↩</a></p>
|
<p>There are some <em>unsafe</em> exceptions to this rule. But you shouldn’t see such use on a real application except maybe for debugging purpose.<a href="#fnref:032001" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="fn:032002">
|
<li id="fn:032002">
|
||||||
<p>For the curious the real type is <code>data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}</code>. All the <code>#</code> as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.<a href="#fnref:032002" rel="reference">↩</a></p>
|
<p>For the curious the real type is <code>data IO a = IO {unIO :: State# RealWorld -> (# State# RealWorld, a #)}</code>. All the <code>#</code> as to do with optimisation and I swapped the fields in my example. But mostly, the idea is exactly the same.<a href="#fnref:032002" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
<li id="fn:03021301">
|
<li id="fn:03021301">
|
||||||
<p>Well, you’ll certainly need to exercise a bit to be used to them and to understand when you can use them and create your own. But you already made a big step further.<a href="#fnref:03021301" rel="reference">↩</a></p>
|
<p>Well, you’ll certainly need to practice a bit to get used to them<a href="#fnref:03021301" rel="reference">↩</a></p>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.fr">Droits de reproduction ©, Yann Esposito</a>
|
<a rel="license" href="http://creativecommons.org/licenses/by-sa/3.0/deed.fr">Droits de reproduction ©, Yann Esposito</a>
|
||||||
</div>
|
</div>
|
||||||
<div id="lastmod">
|
<div id="lastmod">
|
||||||
modifié le : 11/04/2012
|
modifié le : 17/04/2012
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
Site entièrement réalisé avec
|
Site entièrement réalisé avec
|
||||||
|
|
|
@ -210,7 +210,7 @@
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/en/blog/Yesod-tutorial-for-newbies/</loc>
|
<loc>http://yannesposito.com/Scratch/en/blog/Yesod-tutorial-for-newbies/</loc>
|
||||||
<lastmod>2012-04-11</lastmod>
|
<lastmod>2012-04-15</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/fr/blog/2010-09-02-Use-git-to-calculate-trusted-mtimes/</loc>
|
<loc>http://yannesposito.com/Scratch/fr/blog/2010-09-02-Use-git-to-calculate-trusted-mtimes/</loc>
|
||||||
|
@ -262,7 +262,7 @@
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/fr/blog/Yesod-tutorial-for-newbies/</loc>
|
<loc>http://yannesposito.com/Scratch/fr/blog/Yesod-tutorial-for-newbies/</loc>
|
||||||
<lastmod>2012-04-11</lastmod>
|
<lastmod>2012-04-15</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/fr/blog/Higher-order-function-in-zsh/</loc>
|
<loc>http://yannesposito.com/Scratch/fr/blog/Higher-order-function-in-zsh/</loc>
|
||||||
|
@ -394,7 +394,7 @@
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/fr/blog/Haskell-the-Hard-Way/</loc>
|
<loc>http://yannesposito.com/Scratch/fr/blog/Haskell-the-Hard-Way/</loc>
|
||||||
<lastmod>2012-04-11</lastmod>
|
<lastmod>2012-04-17</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/fr/blog/2010-02-15-All-but-something-regexp/</loc>
|
<loc>http://yannesposito.com/Scratch/fr/blog/2010-02-15-All-but-something-regexp/</loc>
|
||||||
|
@ -542,7 +542,7 @@
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/</loc>
|
<loc>http://yannesposito.com/Scratch/en/blog/Haskell-the-Hard-Way/</loc>
|
||||||
<lastmod>2012-04-11</lastmod>
|
<lastmod>2012-04-17</lastmod>
|
||||||
</url>
|
</url>
|
||||||
<url>
|
<url>
|
||||||
<loc>http://yannesposito.com/Scratch/fr/blog/Haskell-Mandelbrot/</loc>
|
<loc>http://yannesposito.com/Scratch/fr/blog/Haskell-Mandelbrot/</loc>
|
||||||
|
|
Loading…
Reference in a new issue