Instructor: 00:01 Let's imagine we now need an additional field that indicates the user's gender. In our JSON, this would be the string "male" or "female." Let me update my model in Elm, and I'll add a field to my user type alias.
00:24 In my decoder, I need to use map4, because I have an additional field. Let me add the field here. The name of the field in the JSON is gender. I'll use gender, a new decoder that I write. I expect that this would be fairly similar to our decoder for membership, so let me just duplicate that, and now make the necessary changes.
00:51 Let me call this value gender and its type is decoder of gender. Rather than starting with bool, I'll start with string, and then I'll map a function toGender, which I define here, and the type of toGender should be string to gender.
01:33 Let's see if that works. It doesn't work, because my pattern matching is not exhaustive. There are infinitely many more strings than indicated for. What if I get another string that is not male or female? Then, I don't really know what to do. In other words, the decoding should really fail here.
01:52 What I need to do now is to change the signature here. I cannot go from just any string to gender, but I can go from a string to a decoder of gender. If I get string male, I can succeed with male. Succeed is a function that returns a decoder that always succeeds with the given value.
02:15 Here, I can succeed with female. Here, I'll fail with an error message. Fail returns a decoder that always fails with the given message. Let me try inaudible now. Now, I have a type mismatch, because string map with this function that returns a decoder, now returns a decoder of a decoder of gender.
02:44 To flatten this decoder of a decoder into a single decoder, I need to use another function that's called andThen. If I say now, you see that everything works nicely, and my decoded user has a gender field with the value set to male.
03:02 It's important to look at the difference. In the case of membership, we were able to use map, because we were mapping a function from bool to membership. In the case of gender, we were not able to write a function from string to gender, so we had to write a function from string to a decoder of gender. These two need to be glued together with andThen, rather than map.
03:22 It can be useful to look at the repo or at the documentation and compare the signatures of map with the signature for andThen. You see it's essentially the same, but here we have a function from A to B, or rather from A to value, and here we have a function from A to a decoder of B. The rest is the same.
03:47 You see exactly the same pattern with other types. For example, if you compare a maybe.map with maybe.andThen, again, here we have a function from A to B, and here function from A to the maybe of B. Of course, in functional programming, functions with this sort of signatures would be called bind.