I only begin to learn Haskell. I've read that it is a pure functional language and everything in it is immutable. So things like input output, writing and reading databases cause mutability of the state. I know there is a thing in Haskell called monads which allow to use imperative features in Haskell like IO Monad
. But I'm interesting is everything imperative in Haskell is implemented with the help of monads? On the HackageDB there are a lot of packages which allow to work with 3d-graphics, databases, parse HTML, write web servers and so on and so forth.
What is the general idea behind all of this? What does allow Haskell to remain pure and simultaneously be applicable for writing all this? I hope somebody will make this clear for me. Thanks in advance!
I came to understand these things using the following analogy, which I'll express with JavaScript.
That is obviously a first thing comming to mind:
var launchRockets = function () {
prepareRockets( queryDBForPreparationParameters() )
launchAllPreparedRockets()
outputResults()
}
You can see an effectful function calling a bunch of other effectful functions, which themselves can produce unknown effects with all the ensuing consequences.
Another way to express this would be to compose a set of instructions describing those effectful computations for some function to later execute. (Ever composed an SQL query?)
var launchRocketsInstructions = [
{
description: "Prepare rockets",
parameters: {
description: "Query a DB for preparation parameters"
}
},
{
description: "Launch all prepared rockets"
},
{
description: "Output results"
}
]
So what do we see in our second example? We see an immutable data tree describing the computation instead of performing it right away. There are no side effects here, and for composing this data tree we can surely use pure functions. And that's what essentially side effects are all about in Haskell. All the infrastructure the language provides: the monads, the IO
, the do
-notation - these are just tools and abstractions simplifying your task of composing a single tree of instructions.
Of course to actually perform these instructions one will have to eventually escape into the wild world of side-effects. In case of JavaScript it would be something like execute(launchRocketsInstructions)
, in case of Haskell it is the runtime executing the root of the instruction tree which you produce with the function main
of the main module, which becomes the single entry point of your program. Thereby the side effects in Haskell actually occur outside of the language scope, that's why it's pure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With