Passed after some naive grammar checker.
This commit is contained in:
parent
4a61dbb8fc
commit
420c6c6a41
6 changed files with 17 additions and 15 deletions
|
@ -3,7 +3,7 @@
|
|||
In my
|
||||
[preceding article](/Scratch/en/blog/Haskell-the-Hard-Way/) I introduced Haskell.
|
||||
|
||||
This article go further.
|
||||
This article goes further.
|
||||
It will show how to use functional programming with interactive programs.
|
||||
But more than that, it will show how to organize your code in a functional way.
|
||||
This article is more about functional paradigm than functional language.
|
||||
|
@ -14,18 +14,18 @@ In reality, the firsts sections will use an imperative paradigm.
|
|||
As you can use functional paradigm in imperative language,
|
||||
you can also use imperative paradigm in functional languages.
|
||||
|
||||
This article is about creating a useful and clean program.
|
||||
This article is about creating an useful and clean program.
|
||||
It can interact with the user in real time.
|
||||
It uses OpenGL, a library with imperative programming foundations.
|
||||
But the final code will be quite clean.
|
||||
Most of the code will remain in the pure part (no `IO`).
|
||||
Despite this fact,
|
||||
most of the final code will remain in the pure part (no `IO`).
|
||||
|
||||
I believe the main audience for this article are:
|
||||
|
||||
- Haskell programmer looking for an OpengGL tutorial.
|
||||
- People interested in program organization (programming language agnostic).
|
||||
- Fractal lovers and in particular 3D fractal.
|
||||
- Game programmers (any language)
|
||||
- People interested in user interaction in a functional paradigm.
|
||||
|
||||
I had in mind for some time now to make a Mandelbrot set explorer.
|
||||
I had already written a [command line Mandelbrot set generator in Haskell](http://github.com/yogsototh/mandelbrot.git).
|
||||
|
@ -33,7 +33,8 @@ This utility is highly parallel; it uses the `repa` package[^001].
|
|||
|
||||
[^001]: Unfortunately, I couldn't make this program to work on my Mac. More precisely, I couldn't make the [DevIL](http://openil.sourceforge.net/) library work on Mac to output the image. Yes I have done a `brew install libdevil`. But even a minimal program who simply write some `jpg` didn't worked. I tried both with `Haskell` and `C`.
|
||||
|
||||
This time, we will display the Mandelbrot set extended in 3D using OpenGL and Haskell.
|
||||
This time, we will not parallelize the computation.
|
||||
Instead, we will display the Mandelbrot set extended in 3D using OpenGL and Haskell.
|
||||
You will be able to move it using your keyboard.
|
||||
This object is a Mandelbrot set in the plan (z=0),
|
||||
and something nice to see in 3D.
|
||||
|
|
|
@ -18,7 +18,7 @@ And the second part more focused on OpenGL and content.
|
|||
> import Graphics.UI.GLUT
|
||||
> import Data.IORef
|
||||
|
||||
For efficiency reason, I won't use the default Haskell `Complex` data type.
|
||||
For efficiency reason, I will not use the default Haskell `Complex` data type.
|
||||
|
||||
> newtype Complex = C (Float,Float) deriving (Show,Eq)
|
||||
|
||||
|
@ -168,13 +168,13 @@ This property is a direct consequence of purity.
|
|||
If you look closely, you see that `allPoints` is a pure list.
|
||||
Therefore, calling `allPoints` will always render the same result and Haskell is clever enough to use this property.
|
||||
While Haskell doesn't garbage collect `allPoints` the result is reused for free.
|
||||
We didn't specified this value should be saved for later use.
|
||||
We did not specified this value should be saved for later use.
|
||||
It is saved for us.
|
||||
|
||||
See what occurs if we make the window bigger:
|
||||
|
||||
blogimage("hglmandel_v01_too_wide.png","The mandelbrot too wide, black lines and columns")
|
||||
|
||||
We see some black lines because we drawn less point than there is on the surface.
|
||||
We see some black lines because we have drawn less point than there is on the surface.
|
||||
We can repair this by drawing little squares instead of just points.
|
||||
But, instead we will do something a bit different and unusual.
|
||||
|
|
|
@ -50,10 +50,11 @@
|
|||
|
||||
</div>
|
||||
|
||||
This time, instead of drawing all points, I'll simply want to draw the edges of the Mandelbrot set.
|
||||
This time, instead of drawing all points,
|
||||
we will simply draw the edges of the Mandelbrot set.
|
||||
The method I use is a rough approximation.
|
||||
I consider the Mandelbrot set to be almost convex.
|
||||
The result will be good enough.
|
||||
The result will be good enough for the purpose of this tutorial.
|
||||
|
||||
We change slightly the `drawMandelbrot` function.
|
||||
We replace the `Points` by `LineLoop`
|
||||
|
|
|
@ -184,7 +184,7 @@ and `(-0.5)` is the number `-0.5` (yes I share your pain).
|
|||
> -- any other keys does nothing
|
||||
> kact _ _ _ _ _ = return ()
|
||||
|
||||
Note `display` take some parameters this time.
|
||||
Note `display` takes some parameters this time.
|
||||
This function if full of boilerplate:
|
||||
|
||||
> display angle zoom position = do
|
||||
|
|
|
@ -34,7 +34,7 @@ functionalMainLoop =
|
|||
Clearly, ideally we should provide only three parameters to this main loop function:
|
||||
|
||||
- an initial World state
|
||||
- a mapping between the user interaction and function which modify the world
|
||||
- a mapping between the user interactions and functions which modify the world
|
||||
- a function taking two parameters: time and world state and render a new world without user interaction.
|
||||
|
||||
Here is a real working code, I've hidden most display functions.
|
||||
|
|
|
@ -23,9 +23,9 @@ begindiv(intro)
|
|||
en: %tldr A progressive Haskell example.
|
||||
en: A Mandelbrot set extended in 3D, rendered using OpenGL and coded with Haskell.
|
||||
en: In the end the code will be very clean.
|
||||
en: The meaningful stuff will be in a pure functional bubble.
|
||||
en: The significant stuff will be in a pure functional bubble.
|
||||
en: The display details will be put in an external module playing the role of a wrapper.
|
||||
en: You'll can use this kind of functional organization even in imperative language.
|
||||
en: Imperative language could also benefit from this functional organization.
|
||||
fr: %tlal Un exemple progressif d'utilisation d'Haskell.
|
||||
fr: Vous pourrez voir un ensemble de Mandelbrot étendu à la troisième dimension.
|
||||
fr: De plus le code sera très propre.
|
||||
|
|
Loading…
Reference in a new issue