Monads in Haskell are computational structures that handle context and side effects through three core functions: return (wraps a value into a monad), bind (>>=) (extracts the internal value and applies a function, propagating errors), and the anonymous bind (>>) (ignores the result while propagating errors). The bind operator enables chaining monadic operations while handling errors gracefully, as demonstrated with Maybe types where Nothing propagates through computations. Monads must satisfy three laws: left identity (return a >>= k = k a), right identity (m >>= return = m), and associativity ((m >>= k) >>= h = m >>= (\x -> k x >>= h)). Common monads include Maybe for error handling and IO for input/output operations.
Haskell Monads Explained: A Comprehensive Guide for Programmers
Added:today we are going to close the book on the theoretical aspects of Haskell because today we are going to talk about monads now monads for a lot of people are this magical thing that nobody can explain right and nobody really understands but that really isn't the case as we can see here when we look at the info for monads and if we look at the common saying what the minimal function is that we need to have for a Monat we see that there is only one function that we actually need in order to have a monad so this means that if we understand this one function we should be able to understand monads but actually we are going to look at three functions here we are going to look at return the greater greater and the greater greater equals but let's make another observation right now maybe and IO the types and the IO actions that we have seen before are monads so this is really interesting because we have worked with monads before we just didn't know okay so let's look at the very important thing this greater greater equals operator it is also called bind and it works like this we get a monad of type a and a function a to monnet B and then we get a monad B so this is interesting because as we can see here we get the internal type of the monad so in the case of a maybe read a just one has the internal value one and an i/o action for example also has some internal value getline has some internal string so this bind operator seems to be able to extract that value the question is how does it do it well let's look at two examples with the maybes a just one is just what we expect we have the internal value one and then we have this anonymous function here that gets this one as its ex argument and then just puts it back in to adjust why not but then the interesting thing is a nothing with this bind operator gets us a nothing now this seems to be weird because why is that the case shouldn't we get a value well no because a nothing doesn't have an internal value and of course it depends on how you define the spined operator but since a nothing encapsulate some error state very often you know it encapsulates that you have nothing in your hands then it shouldn't return anything but a nothing okay so now that we know that why not write a function with this which we will call maybe add which takes a maybe of X and a value Y and then adds them together the important thing is that we still have to return a maybe after this right otherwise we are not don't have a sound type because the bind operator has to return a monad so we just return this just of the sum of those two values so as we can see here if we do some adding with a nothing we actually get a nothing which is what we want because we cannot add to nothing so the error if some error happened is propagated and if we have a just of one for example and we add a 1 to it we get a just 2 so this works just as expected from this we can build something even crazier where we do this with two maybes now we have 2 maybes that we use the bind operator on in order to get the internal values and then we sum them together and throw them into the just constructor again even though I don't have a example here if the second argument is nothing we get nothing if the first argument is nothing we get nothing we only get a just of any value if the two values we throw in here are just okay so now we've seen that we can do it like this but remember there was this one function in the monads which was called return and return should take a value and then return the monad of that value so maybe also has to have a return of course because otherwise maybe wouldn't be a monad so we can use return here and that is true but now let's look at something interesting because the type actually changes so the most general type that we have now is a monad of B's - a monad of B's - a monad of beasts now this still works with maybes right because instead of a monad you can write a maybe because maybe it's a monad but now you could also use this on IO ends and you can use this on any monad that has the internal internal type that is in this num type class so you could use anything basically you could use a reader you could use some some network sockets if you get a number out of the monad you can use it with this maybe add function and now we can think about renaming this function leading up to the best joke of this whole series we will call this function monad with two DS because it's a magnetic ad right that was worth it okay so let's look at this function again and when looking at this function again we maybe see that okay if we want to now use even more monads if we want to have even more arguments this syntax becomes really convoluted and a bit ugly because we are using this operator the spined operator all the time with an anonymous function definition this is not really the way to go is it and no it isn't which is why there is an alternative syntax that we have already seen and it's the du notation because if you have a bar where you say well the Monad em gets bound to this anonymous function with the argument X this is the same in the dew notation as saying well X with this left arrow M which says nothing but well take the value of the internal value of M and put it into X and then do something else but again remember if there is a fault he state in our monad so for example if the maybe is nothing or even IO has some internal exception then we actually because the dew notation is nothing but the bind operator then we actually propagate this error through so we don't have to think about errors in this case we always think about getting a value but we can be sure that if there's an error if for example and nothing is returned then this is just propagated through so this is great because this lets us build pure functions that can still handle errors and exceptions that happen on the side right and using do notation we can actually rewrite this a monad function and it looks like this and let's just go through it we have the Monad x' x and y the monads MX and my of course and we get those values with x left arrow m x and y left arrow and y and then we return the sum of those two great so maybe let's maybe look at something interesting the actual implementation of a monad for them maybe because it's actually really easy so we have this bind operator here and we do a matching I don't think I have mentioned this in this series but this is also a way of doing pattern matching and here we match the M to nothing and in this case we just return nothing and if we have a just of X we apply the function to it right this is exactly what binds should do and a return of any value is just a wealth just of that value great so this is how a monad can be instantiated in and if you have your own type for example for a random number generator or for something that has to hold a state you can use it just like this okay so we've talked about the most important thing the bind let's talk about this one fail what does that do well fail is often not implemented and you don't have to implement it if you don't want to it takes a string and then returns a monad now the funny thing is that the default implementation is that fail passes the string to the function error and error doesn't return a monad it actually just ends your program right there with an exception so yeah fail is used in order to have some well error in your program pop up for example let's say you do some network code and some exception shouldn't happen like a socket gets closed prematurely for example then you can just call fail for example and if your monad can handle that if your Monat can handle the error code and then somehow encode it in its monad that's great because then you get a monad but if it doesn't implement the fail function it will just pass it to error and just end the program right there okay so that's fail we've talked about return and bind let's talk about the last one I don't think this has a special name at least I didn't find one the greater greater so what is the greater greater well I will call this the anonymous bind or the unbind I don't know well let's look at its implementation its default implementation of never changes it's the following m2 n is nothing but binding m to an anonymous function where we drop the the name for this argument so we just ignore the value that we get and just continue with whatever we wanted to do the important thing is that let's say a fault he stayed happened M then this faulty state is propagated through right so then we don't even go into this anonymous function but if everything was alright we just ignore its value so we can see here that if something went wrong right so nothing just means something went wrong now if something went wrong right at the beginning we don't return just one we return nothing but if we have something like this where like the second case where we have a just one so something went right and then adjust to then we return just two and of course if we have just one and we want to return nothing we've returned on nothing so what is this used for why do we need it well an act with the anonymous bind to some expression is the same as doing it in the du notation with just no regard for the value we get back where do we need this well for example put string Ln and put char in all of those output functions that's a typical use case where we don't care what the return is but we still want to do some error checking right because this put string Ln could fail and in this case we should propagate this error through and this function does just that but it's just not as messy with putting a name on every value that we get because for example in the case of put string Ln we have an io of the empty tuple and we already know what that value is it will be the empty tuple so that's a case where we just want to ignore that value and that's how we do it with this operator and now you don't have to define this operator again it's just automatically defined with the default implementation that we have right here okay so now we are almost done let's talk about the monad loss because there are some laws that if you have a monad your monad should abide by these laws so let's look at this the left identity is the following returning a and then a bind to K should be the as ka because return a should return just that the a right it should return a monad with the encapsulated value a and throw that to the function K so that would be the same as just throwing that value to the function K right it should be the same okay so let's look at the right identity where we have some monad which we bind to return well of course we get the value from that M and then we put it into return which in that case should just return the monad the important thing is that this has to be the same M right internal States shouldn't change this identity should be kept alive so and lastly monads should be associative or the bind operator should be associative it shouldn't matter whether you first find m to some function k and then bind that to H or if you do it the other way around where you say well M is bound to this function that takes this argument then you know does the there's does the actual binding operator and this just shouldn't matter the the way of of doing this evaluation should be irrelevant okay
Up Next

Symmetric vs Asymmetric Encryption Explained
@ITkFunde
13.5K views•2022-03-22

BitTorrent Protocol Explained: Piece Selection & Peer Choking
@StevenGordonAU
481 views•2013-02-22

HTTP Requests Explained: GET, POST, PUT, DELETE
@codecademy
103.1K views•2021-10-07

Enigma Machine Mechanics: WWII Encryption Explained
@JaredOwen
13.2M views•2021-12-11
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Computer Science





















![[Haskell] Book of Monads: Attempting to prove Monad Laws with Hedgehog](https://i.ytimg.com/vi/B-3Q-OjSEN4/maxresdefault.jpg)





















