Episode: 3028 Title: HPR3028: Monads and Haskell Source: https://hub.hackerpublicradio.org/ccdn.php?filename=/eps/hpr3028/hpr3028.mp3 Transcribed: 2025-10-24 15:25:17 --- This is Hacker Public Radio Episode 3028 for Wednesday 11 March 2020. Today's show is entitled, Monads and Haskell, and is part of the series, Haskell. It is the first show by new hosts CRVS, and is about 21 minutes long, and carries an explicit flag. The summer is a hopefully not too rambly introduction to functives and monads in and out of Haskell. This episode of HPR is brought to you by An Honesthost.com. Get 15% discount on all shared hosting with the offer code HPR15. That's HPR15. Better web hosting that's honest and fair at An Honesthost.com. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . that are lists of other types, and this is very simple and very important to understand. Also there is this well-known other monad, which is also a functor, which is the maybe monad. It goes from the category of Haskell types to the category of maybe a type, maybe types. So these are types that can be either nothing or just something. Just something can be really anything, really. But nothing, nothing and just are the keywords that like the type constructors. Nothing is, you can think of it as, it's a nullary type constructor in the sense that it takes nothing, and it is nothing. Just like, think of it as none in Python. And then the just operator takes an object of any type and produces a type of and produces a type of maybe that initial type. Okay. So I already dropped the f word here, the functor, of course. And now what's so formidable about them? Well, nothing really. The funters are just this, you can really think of them as design patterns, where you have, they have these properties that you can map over them. Or the most important part of a functor is that, not sure, you know how to take an object from type a to type f of a, f being your functor. And you also, if you know how to take an element of type a into type V, you also need to know how to take an element of type a to type, type f of a to type f of b. And this is what we mean when we say that, well, funters are the things that you can map over. So just like if you have a list, you can map over the list by substituting each element. You can map f over a list by substituting each element of the list with f applied to that element. Same thing with funters. If you have a now a functor f, you can take an element of type f of a by mapping a function f from a to b into an element of type f of b. And here, basically, you would go from, for example, from a list of integers to lists of strings by, by showing, by doing show on the string. For show is the function that basically takes any object that is showable and makes a string out of it. For example, if I do show three, then I get the string, the string whose only character that only has the character three. Okay. So that is what a functor is. And it's nothing really more. And like this is sort of the, the tau of funters. So what about monads? Well, monads appear in, and this is how I learned about them. It was in while studying category theory. Basically, a monad is a functor from a category to itself. So a Haskell Functor can be a monad that has two things. One, it has what is called a natural transformation from the identity functor to itself, meaning that basically if I have any object, then there is a function, not a functor, a function that maps that object, that type to the type to monad of a. So a function that maps every element of type a to type monad of a. And that is, that an Haskell is called the return functor, the return function, which is pretty different from returning other languages. And finally, you have this product operation. And the product basically says that if I have a monad applied to itself, then I can get the monad applied only once. So I have, I say I have a monad M. So if I have M of M of A, then I have a function that takes M of something of type M of M of A, and I'll put something of type M of A. And it's important that there are functions here. So this is basically what makes it an international transformation, is that there are functions that you don't actually need a functor to go from one category to the other, because you stayed within the same category. Okay. However, this is not the case this seem. And so I wanted to learn about fun about monads in Haskell. And so I tried to apply this intuition. And that just got me more confused. Because when you reply, when you when you define the monad in Haskell, and remember, monad is a type class. So it has it's these interfaces that you need to define. And interfaces are the return function. And this other binary operation that you call bind. And how is bind defined? Well, bind is defined as a function that takes an element of type monad of A and a function that takes a type A and produce a type monad of B. And then producing is a function that produces an element of type monad of B. Okay. So how do you actually get this from this operation that I said that I said before, this function that I said before that takes a type monad of monad of A into type monad of A. Well, it's pretty simple, really, because a monad is a function so you can map over it. So if you have a function, if you have an element of type monad of A and a function that goes from type A to type A monad of B, then you can apply that function on over, you can map that function over the monad of A to get an element of type monad of monad of B. And once you have an element of type monad of monad of B, remember that what defines a monad in terms of category theory at least is this having this aside from the return is having this operation that takes an element of type monad of monad of A to an element of type monad of A. And here I have an element of type monad of monad of B, so I can get an element of type monad of B of B. And this is the absolutely natural way of implementing it. However, in Haskell, you need to do it the other way around. You need to define how you do this operation, a monad of monad of A into monad of A from this bind operation called bind that takes an element of type monad of A, a function of type a to monad of B and produces an element of type monad of B. And so what is so difficult here is that when you look at the types and now you want to figure out how would you create your your product operation. And here is this product because it's quashing two monads in one, two applications of a monad into one. Well, how would you get it out from just the monad of A? Just using the bind because this is what you use to define the monads, so you need to be able to define everything else you could eventually do with a monad from it and return of course. But in this case, we only really need this part. So it's actually exceedingly simple. All you need to do is to pass the is to define the operation. So there's an IEV intuition, which is once we once you see that what the bind operation does is it maps over the monad, maps the function, the second argument over the monad application and then applies this product. You just need the monad application to do nothing and then you will get the product out. So this gives you an IEV idea, which just says, well, bind, apply bind, where the second argument is just the identity. And the identity is of course the function that does nothing. It takes a type A and produces a type A. However, this should not type check because we actually need a function of type mod out of A, mod out of A. We need to give it a function from type A to mod out of B. However, it does work. So it does work. It works and you get what you expect out. If you give it if you give it in the list, a list containing only containing a single list with the one inside and you bind it to the identity ID, you get just the list with the single element that had there that was within the list inside. Or rather, if you do it, if you do a list of lists, what you get is all those lists joined together, which is what gives the operation the name in Haskell join, which can be obtained from data.monad. Okay. So basically, I just wanted to explain why this works. So the naive intuition, the naive, so basically I just wanted to say, well, there's this naive idea. And now I wanted to explain why this would actually work. And the idea is pretty simple, really. So the main hang up is that the identity function goes from type A to type A and not from type A to mod out of B. However, these are, of course, dummy types. A is a dummy type. And if we let A equals to mod out of B, then because we're inputting a mod ad, we're mapping this over something that is of type mod out of mod out of A. We're mapping over the first mod out. We really have a type element or type mod out of A to mod out of A. But if we let C equals to mod out of A, then we now have an element function of type C to mod out of A. So it does in the end type check once we rename that, once we rename the types to give us a function of type A to mod out of B. And so I have like some show notes on a post I wrote on my blog, which I will just add it to the show notes and the link also. And yeah, that's all I had to say for today. And thank you for sticking with me and have a nice evening. Oh yes. And follow me on social media or something. I don't know. You don't need to. No, you don't. Yeah. See you next time. This is CRVS for Hacker Public Radio. Have a nice evening. You've been listening to Hacker Public Radio at HackerPublicRadio.org. We are a community podcast network that releases shows every weekday Monday through Friday. Today's show, like all our shows, was contributed by an HBR listener like yourself. If you ever thought of recording a podcast, then click on our contributing to find out how easy it really is. Hacker Public Radio was found by the digital dog pound and the infonomican computer club and is part of the binary revolution at binrev.com. If you have comments on today's show, please email the host directly, leave a comment on the website or record a follow-up episode yourself. Unless otherwise stated, today's show is released on the Creative Commons Attribution ShareLight 3.0 license.