Sara Lichtenstein, Cameron Gera, and Taylor Fausak get recursively drunk on semigroups and monoids. Episode 26 was published on 2020-10-13.
>> Hello and welcome to the Haskell Weekly podcast. I'm your host, Taylor Fausak. I am the lead engineer at ITProTV. And with me today is one of the engineers on my team, Cameron Gera. Welcome Cam.
>> Hey Taylor, it's good to be with you. Well today is a special episode of Haskell Weekly. We have a guest. We have someone else from our team here at ITProTV, Sara. How's it going today Sara?
>> It's going good. Thank you all for having me.
>> Well, awesome. Sara it's so exciting to have you here today with us. It's also an exciting month in the world of open source because it's Hacktoberfest. Which means we have a lot of opportunities to commit and contribute to open source projects that are going on all over the world. So you know if you check it out it's at Hacktoberfest.DigitalOcean.com and there you can kind of figure out what it's all about and get started on you know maybe even get a free T shirt if you're able to contribute what they need.
>> Anything for a free T shirt.
>> Exactly Sara. Well here at Haskell Weekly we wanted to share a project called Learn4Haskell that is actually a part of the Hacktoberfest event. And it's gonna give you the opportunity to get more familiar with Haskell and also get that free T shirt I was talking about earlier. But you know, that's about it for the events and things that are going on from our side. But today we have some really great content. So Taylor, what are we talking about today?
>> Today we're gonna be talking about getting recursively drunk with monoids, which is a blog post by Simon Shine. And this is really exciting because we're in the spookiest month and what's spookier than a recursive cocktail? I can't think of anything.
>> Mmm. Love me some recursive cocktails. That was Friday night. Definitely got hit with that.
>> Take a drink, and then you take another drink. That's recursion, right?
>> But for me, you know, someone else is pouring the beer on the other side, so it just kept coming. Gotta funnel that every once in a while.
>> That's true.
>> We decided to dig into this blog post because we like semigroups and monoids, but this is a really light hearted take on it, even though it is still informative so you can laugh and learn at the same time.
>> It's definitely the funniest blog post I've read in 2020. Every good blog post should include a Rick and Morty joke, in my opinion.
>> Yeah, that's kind of a low bar to clear for 2020 though. I mean, there's not a lot of good stuff going on in this year, but this is one of them.
>> But this blog post is a shining star!
>> Very true. As you can guess from the title. This blog post is about monoids and also about semigroups, which are, you know, a related concept. But I think those can sometimes scare people away. And I'm curious. Cam, do you feel like the first time you heard about semigroups and monoids were you scared or you like, what is that?
>> Yeah, it was a little bit of both. You know, there's inquisitive side of it, you know. I never really heard about it. I never really had an experience. So you know, it's that mystery. What is it? And you know, coming to read this blog post and actually the blog post that inspired this one, which is in the getting recursively drunk with monoids post. It kind of allowed me to kind of just get a good firm definition of what semigroups and monoids are, which semigroups are a way to combine two items. And, you know, in Haskell we have we can derive an instance for that, whether it be custom or just via deriving like we talked about last week in the Haskell Weekly podcast. And, you know, that allows us to merge various maps and different data structures that have a lot of commonality. But we don't wanna have to always do the boilerplate around that. So, uh, you know, that was really cool. And, you know, one fact about the semigroup is it carries over the law of associativity. So, in mathematics, you've probably experienced that or learned about it in algebra, uh, kind of that fun stuff that we all learned back in sixth, seventh, eighth grade. And, you know, sometimes we forget when we program and we're like, oh yeah, that's really nice. So.
>> Yeah, and just in case anybody has for gotten since sixth grade or whenever they learned it in the first time associativity is where If you want to add, like, let's say X plus Y plus Z, it doesn't matter if you do X plus Y first or Y plus Z first. Um and it can be instructive to think about things that aren't associative. So, like division. It matters which one you do first. But with addition, it doesn't. So you're free to do them in any order. And that's what a semigroup requires you to be able to do.
>> Right. And then we've got monoid which allows you to have a default implementation for a semigroup. So you know, when you're dealing with a map, you can merge a map that has items and merge a map that has nothing and monoid is kind of what allows you to do that on so yeah.
>> Ye old mempty.
>> Mmm mempty.
>> Mmm mempty.
>> Whenever my stomach gets mempty. I gotta hit the pantry and make sure I got some food. Especially.
>> You gotta mappend some food in there.
>> Oh yeah, all about them monoids and semigroups
>> If you got a mempty tummy you gotta mappend some snacks.
>> Mmhmm. Or some of Sara's delicious cookies. Ship them to me!
>> But anyways, back to this blog post. Um, yeah. So, Taylor, you know, kind of, dive in more. What was the the big talk?
>> I think the big idea here was that if you squint a little bit, you can model cocktails as monoids. And I have to say, as somebody who has made a handful of mixed drinks myself, there's some questions lingering on if you can really do this or not, but I'll ride with it for this post. You know so when they say a cocktail could be modeled as a monoid we have to kind of meet all of the things that we just laid out. We have to be able to combine cocktails associatively, and we have to have an empty cocktail. Now the empty cocktail is really easy because it's just nothing. No cocktail.
>> But you gotta be careful when combining your cocktails. Remember beer before liquor. Never sicker liquor before beer in the clear.
>> Or you end up with a Molotov cocktail. You know, that's also very dangerous.
>> I hope we're not talking about that type of cocktail in this post.
>> I mean, who knows?
>> These seem like the drinkable ones To be fair. Gin and tonic is usually for drinking. Molotov, I believe, is for lighting things on fire.
>> Yeah, I gotta rewatch The Good Place to make sure I understand that.
>> To be fair --
>> -- though this post is definitely lighting a fire in us
>> And this conversation, right? It's sparking this conversation.
>> Exactly. It all comes back.
>> Well, anyways, we've got cocktails. We're talking about real drinking cocktails here, right? One that has a name, you know, like sex on the beach or gosh, rum and coke. Yeah.
>> Old fashioned.
>> Old fashioned, gin and tonic. Like Sara said earlier. Yeah, and this one actually talks a lot about gin and tonic and lemon.
>> That's actually in the underlying post. Which good stuff.
>> The underlying post was so funny because the idea of combining a mojito and the rum drink sounds disgusting, like you can do it in code. But if you physically combine those drinks to ingest, that would be very gross.
>> Oh, yeah. We're not saying that if you mappend two cocktails, you're gonna end up with a good cocktail. Just that it is still technically a cocktail.
>> Yeah I mean, I'm just not sure that guy was 21 yet, so he probably hasn't tried it yet.
>> This is all in theory, theoretical cocktails.
>> Right? But anyway, so they've got name and ingredients which they kind of talk about in this post. Uh, you know, and there's something called the super drink, which I don't know what the heck that is.
>> Yeah, this is from some Dutch computer science paper. I could not read it, but it looked very entertaining.
>> You know, the Dutch, They can have a good time.
>> Apparently, they're drinking super drinks.
>> So what is the super drink?
>> I still don't know? You didn't answer the question. I mean, I read the post. I don't speak Dutch, so I couldn't read the post.
>> The post lays it out here as one part gin, two parts lemon and three parts super drink. So a super drink contains super drink. And this is where the recursion in comes in
>> Oh my gosh, my mind is blown.
>> It's just super drinks all the way down.
>> Sure is.
>> Yeah. I mean, not gonna lie. Missed that this whole time I've read this blog post like four times. Still didn't click which I gotta slow down and work on my.
>> Slow down, pour yourself a super drink and then understand super drinks.
>> Good stuff. Anyhoo, um so last week we talked about deriving right Kowainik wrote a blog post in very great detail about it. And we talked about that in the previous edition. And, you know, we're talking about semigroups and monoids, which are type classes in Haskell. And could we derive these things?
>> So sort of. For the semigroup instance unfortunately we couldn't because the way that they chose to represent ingredients behind the scenes is a map from the particular ingredient, like gin to the amount, like one part or two parts. And when you want to combine two sets of ingredients, you have to add those together. So if you have one cocktail that has one part gin in it and another cocktail that has two parts gin, you want to end up with three parts gin. Hopefully, everyone can follow that math. Um, but if you use the derived instance for semigroup. Since they're using maps behind the scenes maps will just pick one of those to win. So if you're one part gin drink was the quote unquote first one, then your result would only have one part gin. So you'd be dropping some parts of your cocktail so you would not be able to derive that part unfortunately, But the monoid part, you could, because the empty cocktail is the same as the empty map. So we're good there.
>> I mean, I think the empty cocktail means give me some more. Isn't this a recursive function. Doesn't this never end?
>> The infinity cocktail? I like it.
>> Good stuff.
>> The super drink. It is the infinite cocktail.
>> Get you that super drank or drunk
>> Gets you super drunk. Yeah.
>> It's good to remember that empty cocktails are always empty for the mempty, but you have to do something special so that you get all the parts of your cocktail together.
>> Yeah, and and that's a that's a very good thing to point out, because the derived instances are handy, but it means you're getting the default behavior. And here we need something other than the default.
>> So yeah thanks thanks, Taylor, for that information. What about, you know, kind of normalizing part of the combination. They talked about this in the blog post. Could you expand a little bit on how they resolved it and what they're you know, they had a hypothesis. And what what was the result that ended up happening?
>> When they're talking about normalizing for cocktails, what they're talking about is taking a recipe that says something like two parts gin to four parts lemon and reducing it into something that's equivalent, but hopefully simpler, like one part gin, two parts lemon. Because you probably wouldn't give a recipe to someone that is more complicated than it needs to be because they're drinking these super drinks. They're gonna need things to be simple so that they can follow along.
>> Well, my margarita mix that I have in the fridge does say two parts. Uh, wow.
>> Tequila, Thank you. And four parts mix.
>> Magrarita mix.
>> So yeah, so I mean, obviously that manufacturer didn't understand that they could simplify it, and maybe they didn't want to because of what they found out in this blog post.
>> It turns out that normalizing has some gotchas because we've been talking about combining things and in particular being able to combine them in any order you can't normalize after you combine because it may change the thing that you get it the end. So if you're trying to combine three cocktails together, it will. You'll get a different result if you combine the first two and then the third one or the second two and then the first one. And that's because this normalization step removes some of that information from these cocktail recipes.
>> Mmhmm. So it wouldn't get as good of a drink. Well, at least we figured out what a super drink is, You know, at the end of this, they've actually ran the function and created what is apparently the super drink, which is 182 parts gin, 121 parts lemon and holy cow. That's a lot of alcohol.
>> Enough for a party.
>> Yeah, we did the math, and, uh, this comes out to about eight liters or two gallons of gin. And I don't know about you. I have a relatively well stocked bar, but I don't have two gallons of gin in my bar.
>> You don't just keep two gallons of gin on hand,
>> Not even around Christmas.
>> I mean, I don't think you would remember where you put the gin or where you would get gin after drinking that much gin, so.
>> That's very fair.
>> I think it's a good thing you don't have to gallons of gin laying around.
>> Sadly, it means I will not be able to create and then sample one of these super drinks.
>> Yeah, we need you at work on Monday, and I think you'd still be out of it if you had a sip. Now, I don't think he'll be back for Monday's work.
>> I agree. I wouldn't be back.
>> I know what our next engineering hang out should consist of, though.
>> I'm not so sure.
>> We'll just do a shot of super drink. How about that? That way.
>> You know, we don't have. Yeah, maybe we'll see if we could do some simplification here. Doesn't seem like it's gonna be possible, but we'll find out. But yeah, so you know. And you know, this is a fun contrived example of, you know, semigroup instances and what they do and how they work. But for us in our day to day at ITPro. As you know, web application developers and API engineers. You know, we do deal with us a lot because we have, you know, various metrics that need to be combined. So You know, if someone's watching a video at ITProTV, You know, we need to know, you know, figure out how to merge two events that have occurred. So they've watched thirty seconds and thirty seconds. Oh, they've actually watched a minute of ITProTV. And so, you know, we have those, you know, semigroup examples that we. Actually I don't think we have any customization, but I could be wrong. Taylor, do we have any customization there?
>> I don't know that I would call it customization, but these types that we have, like you mentioned for amount of time that a user has watched an episode, they're effectively wrappers around integers. But integers don't have a semigroup instance, or a monoid instance because there are multiple possibilities. You could choose addition or multiplication. So, really, what we're doing is choosing addition for these instances and then using that.
>> Right. So we don't do anything super fancy but it's super practical and helpful for us when trying merge these things together. Sweet.
>> Yeah, and one of the upsides here is that we don't define that many semigroup instances in our code base. But we use a lot of functions that rely on semigroup instances. So things like, you know, foldMap or, uh, that's the only one that immediately comes to mind. But stuff like that where we don't have to write all these little utility functions to smush a bunch of these values together, they're already there for us.
>> Yeah. And, you know, I think that you bring up a good point there about, like, semigroups were great to merge generally two things together. But if you have a list of things you probably want to reach for a foldable instance, um which, you know will allow you to kind of create the same merging, but over a larger list of, um, whatever it may be.
>> Yeah. So if you had a list of cocktails like maybe an entire cocktail recipe book and you wanted to combine them all into one cocktail, that's that's where you need foldable.
>> Yeah, I don't I think I think that would be a legal in the lower 48 states? Well, any who, thanks thanks for sharing that stuff. And, you know, we want to give you some, you know, real world examples from from a contrived example. Uh, and, you know, I think we've got a good idea of what semigroup and monoid are now and how to apply them and use them. Um, yeah. I mean, do you have anything else to add here, Taylor?
>> I think that'll about do it for me. How about you, Sara?
>> Same. This has been very fun. I feel like we've learned a lot about semigroups and monoids and also about cocktails. So very informative podcast day
>> Win win win. All right, y'all. Well, thank you for listening to the Haskell Weekly podcast. I've been your host, Taylor Fausak. And with me today was Cameron Gera and Sara Lichtenstein. If you're interested in learning more about Haskell Weekly, please check out our website, which is HaskellWeekly.News. Or you can check us out on social media. Our Twitter handle is @HaskellWeekly. Our Reddit user name also u/HaskellWeekly. And if you want to contribute to the Haskell weekly newsletter or you have a blog post that you'd like us to talk about here on the podcast, please let us know on GitHub. And our GitHub user name once again, HaskellWeekly.
>> Nice, awesome. Well, And also, you know, we want to thank our sponsor ITProTV for allowing us to create this podcast. And if you're interested in learning more about ITProTV and subscribing to the content we have available, we would love to offer you a coupon code the coupon code is HaskellWeekly30 which will give you 30% off all of our memberships, and we'll be able to give you access to an entire library of IT content. So please check it out. Free subscription as well, if you'd like to kind of sample and see what's available. But we would like to just give a shout out to them and all the incredible things they do and we're just so grateful they let us do a podcast like this.
>> Very much so. Thanks again for listening and we'll see you next week.