As I understand it, monads help solve the problem of sequential computation in Haskell but the concept is not limited to that. For example, how would you consider the monadic properties of data type like Maybe or Either to be (exclusively?) interpreted through the lens of sequential computation? What about commutative monads where the order doesn’t matter?
The `Monad` instance for `Maybe` and `Either` is precisely for doing sequential computation!
Consider the following:
myBigSubroutine :: Maybe Int -> Maybe Int -> Maybe Bool
myBigSubroutine ma mb = do
a <- ma
b <- mb
return (a > b)
Here we are sequencing the "effect" of optionality. `ma` must be evaluated before `mb` and if it returns a `Nothing` then we short circuit and do not evaluate `mb`.
Which in this case is equivalent in this example, however I'm trying to stress the sequencing. Imagine `mb` had some very expensive computation in it, then it will remain an unevaluated thunk if we shortcircuit on `ma`.
it’s clearer to me what the intent is. I’m not sure why the other syntax is so hard for me but it feels hard to understand for some reason.
We can write `myBigSubroutine` with case matching:
case ma of
Nothing -> Nothing
Just a ->
case mb of
Nothing -> Nothing
Just b -> Just (a > b)
In fact, the `do` notation version desugars to something equivalent to this snippet.
The motivation for using the `Monad` instance (and thus `do` notation), is that it allows us to be polymorphic over the effect described by `>>=` (and thus `do`).
This lets us have a customized version of sequencing computations specialized to whatever "effect" we need, not just casing on optional values.
No - either one can be evaluated first, with the other being short-circuited. If you swap the order of those lines, the function is exactly the same (in terms of inputs and outputs, at least).
We can then inline the definition of `>>=` and `return` to get:
case ma of
Nothing -> Nothing
Just a ->
case mb of
Nothing -> Nothing
Just b -> Just (a > b)
Imagine that `mb` is actually a really expensive computation that we don't want to perform unless `ma` returns a value. Sequencing our case statements in this way allows us to do that. `mb` will remain an unevaluated thunk until `ma` evaluates to a `Just a` value.
Comments
As I understand it, monads help solve the problem of sequential computation in Haskell but the concept is not limited to that. For example, how would you consider the monadic properties of data type like Maybe or Either to be (exclusively?) interpreted through the lens of sequential computation? What about commutative monads where the order doesn’t matter?
The `Monad` instance for `Maybe` and `Either` is precisely for doing sequential computation!
Consider the following:
Here we are sequencing the "effect" of optionality. `ma` must be evaluated before `mb` and if it returns a `Nothing` then we short circuit and do not evaluate `mb`.I think the commenter who mentioned syntax is on to something. If I write this
it’s clearer to me what the intent is. I’m not sure why the other syntax is so hard for me but it feels hard to understand for some reason.The `do` block I showed is more like this:
Which in this case is equivalent in this example, however I'm trying to stress the sequencing. Imagine `mb` had some very expensive computation in it, then it will remain an unevaluated thunk if we shortcircuit on `ma`.We can write `myBigSubroutine` with case matching:
In fact, the `do` notation version desugars to something equivalent to this snippet.The motivation for using the `Monad` instance (and thus `do` notation), is that it allows us to be polymorphic over the effect described by `>>=` (and thus `do`).
This lets us have a customized version of sequencing computations specialized to whatever "effect" we need, not just casing on optional values.
No - either one can be evaluated first, with the other being short-circuited. If you swap the order of those lines, the function is exactly the same (in terms of inputs and outputs, at least).
This `do` syntax desugars to binds like:
We can then inline the definition of `>>=` and `return` to get: Imagine that `mb` is actually a really expensive computation that we don't want to perform unless `ma` returns a value. Sequencing our case statements in this way allows us to do that. `mb` will remain an unevaluated thunk until `ma` evaluates to a `Just a` value.monads help solve the problem of sequential computation in Haskell
It probably confuses people because this is a problem haskell created for itself.