Transcript from the "Decoderizing" Lesson
>> Richard Feldman: To the code! For a real-world example. Pun intended, because this is the real-world SPA example. All right, so, for an example of and then, I want to look at our, whoops.
>> Richard Feldman: ISO 8601, so we mentioned previously that we have this notion of ISO 8601 encoded dates.
[00:00:25] This is in the previous section, we talked about this. So this is a string format, and we have a library called Iso8601, which converts from those date strings to the POSIX timestamp, which is what we actually wanna store in our model, okay? So right here, we have a little helper function that decodes it, because we want to expose an iso8601Decoder.
[00:00:49] The way that it works is, it is a two-step process. First, we say Decode.string because we know it's going to be a string coming from the server. And then we pipe that to Decode.andThen, a function named fromString which is our little helper here. fromString takes the ISO 8601 string which we've successfully decoded, but at this point, all we know is it's some sort of string.
[00:01:07] We don't actually know if it's got a date in there. If it's got a date, we don't know if it's malformed. We don't know anything about it, other than that it is a string. So then we call Iso8601.toTime which takes a string and returns a result. So in the Ok branch of that result, we've got a successValue which is a Time.Posix.
[00:01:26] And in the Err case, we have a fail, which is to say that something didn't work out above the date. And here we're calling it Decode.succeed, on the success branch, with the successful value, which is to say, the POSIX timestamp. And the Err branch, we're just sort of disregarding whatever failure string that it gave us, because we don't really care.
[00:01:45] And we're just saying yeah, that was an invalid date of some sort, so we're failing decoding. So this is an example of our using Decode.andThen as a way to turn a successful string decoding into a potential overall decoding failure. Because this decoder's job is not just to give us a string, but to give us an actual POSIX timestamp.
[00:02:05] Now in some cases we might be doing additional validation that's sort of optional in the sense that that validation might be on top of what we're normally doing. I wanna check that the string is not empty, something like that. In this case, we don't really have a choice.
[00:02:17] How can we possibly give it a valid time.Posix value from a string without handling both of these possibilities, right? Iso8601.toTime gives us back a result. So if we didn't wanna use decode.andThen, I mean, how do we possibly map that to a successful value? We need, in some way, to handle this error case.
[00:02:36] And if we weren't using decode.andThen, we'd be forced to succeed. And say something like, I don't know, assume it's the epic, which would be much worse than failing the decoding, which is a much more accurate representation of what's going on here. So we can see in this simple example on the screen, sort of the power of decode.andThen.
[00:02:55] Not only could be from here, say success. We could actually do this again if we wanted to. We could pipe this right here, because this is a decoder, to decode.andThen and just keep going. We can create an entire branching conditional system of decoders that checks one after the other.
[00:03:13] And makes sure that all of them pass, every single one of them, those additional validations that we want to perform, before ultimately resolving to this one decoder. And all that logic is going to be wrapped up inside of that one decoder value. And anybody who is using it doesn't necessarily need to know all of the hoops it's jumping through to make sure that this data is actually okay.
[00:03:31] We can also note that it's entirely possible that we could implement decode.map in terms of decode.andThen. It essentially has the same semantics, except that you always succeed. So if we wanted to, yeah, that would be no problem. If we ever use a library that implements something like andThen with those same semantics, I don't know, I really wish this library gave me map, but it doesn't.
[00:03:50] Well, the good news is you can implement it yourself. And that it's so powerful that it's actually capable of implementing map in terms of itself.