For a long time Json.Decoder was a mystery to me. I could use it but I just didn’t get how it worked, since e.g. Decode.string clearly returns a Decoder String and not a function how the heck does it know how to take a JSON value and decode it into a string? Or so I reasoned.
Not long ago we were working with form validations, which are very similar, and suddenly it clicked. A Decoder is simply hiding a function that takes a value and decodes it into the target value type. Or in Elm parlance:
type Decoder a : jsonValue -> a
Which is actually not valid Elm, but hopefully a correct understanding.
that’s broadly the idea, yes. You could re-implement Decoder like so
type Decoder a = Decoder (Json.Decode.Value -> Result String a)
succeed : a -> Decoder a
succeed x =
Decoder (\_ -> Ok x)
-- etc.
you’d need access somehow to the internals of Json.Decode.Value as well
So basically, it is a wrapper around source -> Result error target. The Result allows the decoding to fail. Types of this form have standard definitions for e.g. map, map2 and andThen.
The same idea goes for Parser ctx problem a from elm/parser, Decoder from elm/bytes, really any kind of parsing or validation. It’s always nice when such a general pattern ‘clicks’.
@stoft and I was actually working together on the form validations and shared the epiphany on how decoders work. Looks like I forgot to tell you that I posted about it : Elm/json re-implemented in Elm for learning. I should have mentioned you in that post, because without your realization it would never have been a thing!