- 5.1k
- 3
- 26
- 34
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
FE.exg., that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
FE.exg., a
Maybe Intcan be aJust IntorNothing. Now, if you add aMaybe Intto aMaybe Int, the operator will check to see if they are bothJust Ints inside, and if so, will unwrap theInts, pass them the addition operator, re-wrap the resultingIntinto a newJust Int(which is a validMaybe Int), and thus return aMaybe Int. But if one of them was aNothinginside, this operator will just immediately returnNothing, which again is a validMaybe Int. That way, you can pretend that yourMaybe Ints are just normal numbers and perform regular math on them. If you were to get aNothing, your equations will still produce the right result – without you having to litter checks forNothingeverywhere.
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., a
Maybe Intcan be aJust IntorNothing. Now, if you add aMaybe Intto aMaybe Int, the operator will check to see if they are bothJust Ints inside, and if so, will unwrap theInts, pass them the addition operator, re-wrap the resultingIntinto a newJust Int(which is a validMaybe Int), and thus return aMaybe Int. But if one of them was aNothinginside, this operator will just immediately returnNothing, which again is a validMaybe Int. That way, you can pretend that yourMaybe Ints are just normal numbers and perform regular math on them. If you were to get aNothing, your equations will still produce the right result – without you having to litter checks forNothingeverywhere.
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
E.g., that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
E.g., a
Maybe Intcan be aJust IntorNothing. Now, if you add aMaybe Intto aMaybe Int, the operator will check to see if they are bothJust Ints inside, and if so, will unwrap theInts, pass them the addition operator, re-wrap the resultingIntinto a newJust Int(which is a validMaybe Int), and thus return aMaybe Int. But if one of them was aNothinginside, this operator will just immediately returnNothing, which again is a validMaybe Int. That way, you can pretend that yourMaybe Ints are just normal numbers and perform regular math on them. If you were to get aNothing, your equations will still produce the right result – without you having to litter checks forNothingeverywhere.
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., a
Maybe Intcan be aJust IntorNothing. Now, if you add aMaybe Intto aMaybe Int, then the operator will look at theMaybes wrapping thecheck to see if they are bothJust Ints to seeinside, and if they both have a valid value. If so, it passeswill unwrap the unwrappedInts to, pass them the addition operator and then returns, re-wrap the resultingIntwrapped ininto a newJust Int(which is a validMaybe Intthat says it’s valid; otherwise it), and thus return aMaybe Int. But if one of them was aNothinginside, this operator will just returnsimmediately returnNothing, which again is a validMaybe Int. That way, you can pretend that says it’s emptyyourMaybe Ints are just normal numbers and perform regular math on them. If you were to get aNothing, your equations will still produce the right result – without you having to litter checks forNothingeverywhere.
But the example is just what happens for a Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.) (Also, if you paid attention to the Maybe example, you have noticed that "wrapping a value with extra stuff" is not always correct. But it’s hard to be exact, correct and precise without being inscrutable.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare a patternnew patterns as a thingthings in your program. (The imprecision here is all the patterns have to follow a particular form, so it’sa monad is not quite patternsas generic as a pattern. But I think that’s the closest term that most people know and understand.)
And that is why people find themmonads so confusing: because they are such a generic concept. To ask what makes something a monad is similarly vague as to ask what makes something a pattern.
But imagine what this meansthink of the implications of having syntactic support in the language for the idea of a pattern: instead of having to read the Gang of Four book and memorise the construction of all the patternsa particular pattern, you just write code that implements these patternsthis pattern in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, just by decorating the operations in your code with it, without having to implementre-implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too, of course, teehee), but actually makes code simpler.
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., if you add a
Maybe Intto aMaybe Int, then the operator will look at theMaybes wrapping theInts to see if they both have a valid value. If so, it passes the unwrappedInts to the addition operator and then returns the resultingIntwrapped in aMaybethat says it’s valid; otherwise it just returns aMaybe Intthat says it’s empty.
But the example is what happens for a Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare a pattern as a thing in your program. (The imprecision here is all the patterns have to follow a particular form, so it’s not quite patterns. But I think that’s the closest term that most people know.)
And that is why people find them so confusing: because they are such a generic concept.
But imagine what this means: instead of having to read the Gang of Four book and memorise the construction of all the patterns, you just write code that implements these patterns in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, by decorating the operations in your code with it without having to implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too, of course, teehee), but actually makes code simpler.
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., a
Maybe Intcan be aJust IntorNothing. Now, if you add aMaybe Intto aMaybe Int, the operator will check to see if they are bothJust Ints inside, and if so, will unwrap theInts, pass them the addition operator, re-wrap the resultingIntinto a newJust Int(which is a validMaybe Int), and thus return aMaybe Int. But if one of them was aNothinginside, this operator will just immediately returnNothing, which again is a validMaybe Int. That way, you can pretend that yourMaybe Ints are just normal numbers and perform regular math on them. If you were to get aNothing, your equations will still produce the right result – without you having to litter checks forNothingeverywhere.
But the example is just what happens for Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.) (Also, if you paid attention to the Maybe example, you have noticed that "wrapping a value with extra stuff" is not always correct. But it’s hard to be exact, correct and precise without being inscrutable.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare new patterns as things in your program. (The imprecision here is all the patterns have to follow a particular form, so a monad is not quite as generic as a pattern. But I think that’s the closest term that most people know and understand.)
And that is why people find monads so confusing: because they are such a generic concept. To ask what makes something a monad is similarly vague as to ask what makes something a pattern.
But think of the implications of having syntactic support in the language for the idea of a pattern: instead of having to read the Gang of Four book and memorise the construction of a particular pattern, you just write code that implements this pattern in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, just by decorating the operations in your code with it, without having to re-implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too of course, teehee), but actually makes code simpler.
[Disclaimer: I am still trying to fully grok monads. The following is just what I have understood so far. If it’s wrong, hopefully someone knowledgeable will call me on the carpet.]
Arnar wrote:
Monads are simply a way to wrapping things and provide methods to do operations on the wrapped stuff without unwrapping it.
That’s precisely it. The idea goes like this:
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., if you add a
Maybe Intto aMaybe Int, then the operator will look at theMaybes wrapping theInts to see if they both have a valid value – if. If so, it passes themthe unwrappedInts to the addition operator, and then returns the resultingIntwrapped in aMaybethat says it’s valid; otherwise it just returns anaMaybe Intthat says it’s empty.
But the example is what happens for a Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare a pattern as a thing in your program. (The imprecision here is all the patterns have to follow a particular form, so it’s not quite patterns. But I think that’s the closest term that most people know.)
And that is why people find them so confusing: because they are such a generic concept.
But imagine what this means: instead of having to read the Gang of Four book and memorise the construction of all the patterns, you just write code that implements these patterns in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, by decorating the operations in your code with it without having to implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too, of course, teehee), but actually makes code simpler.
[Disclaimer: I am still trying to fully grok monads. The following is just what I have understood so far. If it’s wrong, hopefully someone knowledgeable will call me on the carpet.]
Arnar wrote:
Monads are simply a way to wrapping things and provide methods to do operations on the wrapped stuff without unwrapping it.
That’s precisely it. The idea goes like this:
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., if you add a
Maybe Intto aMaybe Int, then the operator will look at theMaybes wrapping theInts to see if they both have a valid value – if so, it passes them to the addition operator, otherwise it returns anMaybe Intthat says it’s empty.
But the example is what happens for a Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare a pattern as a thing in your program. (The imprecision here is all the patterns have to follow a particular form, so it’s not quite patterns. But I think that’s the closest term that most people know.)
And that is why people find them so confusing: because they are such a generic concept.
But imagine what this means: instead of having to read the Gang of Four book and memorise the construction of all the patterns, you just write code that implements these patterns in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, by decorating the operations in your code with it without having to implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too, of course, teehee), but actually makes code simpler.
[Disclaimer: I am still trying to fully grok monads. The following is just what I have understood so far. If it’s wrong, hopefully someone knowledgeable will call me on the carpet.]
Arnar wrote:
Monads are simply a way to wrapping things and provide methods to do operations on the wrapped stuff without unwrapping it.
That’s precisely it. The idea goes like this:
You take some kind of value and wrap it with some additional information. Just like the value is of a certain kind (eg. an integer or a string), so the additional information is of a certain kind.
F.ex. that extra information might be a
Maybeor anIO.Then you have some operators that allow you to operate on the wrapped data while carrying along that additional information. These operators use the additional information to decide how to change the behaviour of the operation on the wrapped value.
F.ex., if you add a
Maybe Intto aMaybe Int, then the operator will look at theMaybes wrapping theInts to see if they both have a valid value. If so, it passes the unwrappedInts to the addition operator and then returns the resultingIntwrapped in aMaybethat says it’s valid; otherwise it just returns aMaybe Intthat says it’s empty.
But the example is what happens for a Maybe. If the extra information was an IO, then that special operator defined for IOs would be called instead, and it could do something totally different before performing the addition. (OK, adding two IO Ints together is probably nonsensical – I’m not sure yet.)
Basically, "monad" roughly means "pattern". But instead of a book full of informally explained and specifically named Patterns, you now have a language construct – syntax and all – that allows you to declare a pattern as a thing in your program. (The imprecision here is all the patterns have to follow a particular form, so it’s not quite patterns. But I think that’s the closest term that most people know.)
And that is why people find them so confusing: because they are such a generic concept.
But imagine what this means: instead of having to read the Gang of Four book and memorise the construction of all the patterns, you just write code that implements these patterns in an agnostic, generic way once and then you are done! You can then reuse this pattern, like Visitor or Strategy or Façade or whatever, by decorating the operations in your code with it without having to implement it over and over!
So that is why people who understand monads find them so useful: it’s not some ivory tower concept that intellectual snobs pride themselves on understanding (OK, that too, of course, teehee), but actually makes code simpler.