Files

246 lines
10 KiB
Plaintext
Raw Permalink Normal View History

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.