Transcript from the "Decode.map & Decode.andThen" Lesson
>> Richard Feldman: That brings us to Decode.map and its bigger cousin, Decode.andThen. So there are quite a few map functions in Elm. Here are a couple of them, one is Decode.map. So it takes a function from a to b, and then takes a Decoder a and returns a Decoder b.
[00:00:17] We also have Maybe.map, which looks rather similar, a to b, and then a Maybe a to a Maybe b. And Result.map, again, a to b, this is a little bit different in the sense that it's Result x a, because result has two type variables, to Result x b.
[00:00:33] So all three of these map functions happen to have the same semantics. Which is to say, all of them have a notion of success and a notion of failure. So in the case of decoding, it's literally did decoding succeed, or did decoding fail? And maybe it's do we have a just, or do we have nothing?
[00:00:49] And the result is, do we have okay, or do we have error? And what all three of these map functions do is they say, if we're on the happy path, if we've got a successful decoder. Or we've got a just in the case of maybe, and we've got an okay in the case of result, transform the value that we're holding onto.
[00:01:05] Transform that successful value that we're in the process of decoding, transform the just, transform the okay. Also all three of these disregard the error case. So if we have a failing decoder, this function will not even get called. If we have nothing for the maybe, will not get called, if we have an error, will not get called.
[00:01:25] So all it does is it works on the happy path, it transforms it. It also stays on the happy path, so if you call Decode.map, Maybe.map, or Result.map, if it's going to actually call this function. That is to say it's going to have an okay result or a just maybe or a successful decoder, that's also what you're gonna get out the other side.
[00:01:45] So in all three cases, it only does anything if you're on the happy path. And the one that you get back is still gonna be on the happy path, it's still gonna be a successful result. So this is basically transform the success variant only don't touch the error case at all.
[00:02:00] If it's an error, just leave it alone. Okay, so that's map, let's talk about andThen. So andThen has an extremely similar signature to map, the only difference is instead of a to b, it's a to decoder b. And the difference in what it does is it says I'm going to take whatever you return in this function, and I'm just gonna return that directly.
[00:02:25] So if we're on the happy path, if we're in the success variant, then we're gonna say okay great. We're gonna call this function, and then whatever you return here I'm not gonna wrap it up into success again, I'm just gonna use it straight up.
>> Richard Feldman: So what does that do, what does that give us?
[00:02:41] That gives us a new power that we didn't have with map, and it's the power to fail. So in the case of map, we stay on the happy path. If it was successful before, it's gonna be successful after mapping. With andThen, we can potentially say Decode.succeed at the end of that, in which case we will stay on the happy path.
[00:02:58] We can also say Decode.fail, in which case we have gone from the success path to failure, so andThen introduces the ability to change success to failure. A decoder that was in the process of succeeding, now it has suddenly failed. At the same time it still has the power to transform just like map does.
[00:03:18] So in that sense it's a more powerful version of map. And you know what they say, with great power comes great responsibility, which is why as a general rule, if you can, if map gets the job done. Map is a better choice because you know more about it.
[00:03:32] In the case of map you know that it's only going to keep you on the happy path, whereas andThen you now have more to think about. When you look at some code that's using andThen, you think wait a minute it might actually be changing it to a failure.
[00:03:42] What are the implications of that, that has fewer implications. But, andThen does have more power, and sometimes that's what you want. So, we can get into some specific examples, but while we still have this on the screen, any questions about it?
>> Student 1: So, I'm assuming the andThen, rhe use case is kind of you do some logic to decide if it's this specific value we're gonna fail.
>> Richard Feldman: Yeah, so most common andThen is used for additional validation, where you have some code and it's like, I was able to successfully decode it from the raw JSON. But I actually don't want the overall decoder to succeed unless for example, not only did I get a string, but it wasn't empty.
[00:04:23] If it was an empty string, that's invalid, I wanna fail the decoder right there. Something like that, and we're gonna see an example of that in a moment.