Json2elm: generate pipeline and applicative decoders

I’ve added a few features to json2elm.

In addition to plain elm/json decoders, it can now also generate applicative and pipeline decoders. It also generates the required imports based on the chosen decoder type. You can also choose between noun-based and verb-based function names for decoders and encoders.

Applicative decoders take advantage of the andMap function from elm-community/json-extra and look like this:

accountDecoder : Json.Decode.Decoder Account
accountDecoder = 
    Json.Decode.succeed Account
        |> Json.Decode.Extra.andMap (Json.Decode.field "id" Json.Decode.int)
        |> Json.Decode.Extra.andMap (Json.Decode.field "prefs" accountPrefsDecoder)
        |> Json.Decode.Extra.andMap (Json.Decode.field "user" accountUserDecoder)

Pipeline decoders rely on the NoRedInk/elm-json-decode-pipeline package and look like this:

accountDecoder : Json.Decode.Decoder Account
accountDecoder = 
    Json.Decode.succeed Account
        |> Json.Decode.Pipeline.required "id" Json.Decode.int
        |> Json.Decode.Pipeline.required "prefs" accountPrefsDecoder
        |> Json.Decode.Pipeline.required "user" accountUserDecoder

I’ve also added imports to the generated code, so for example for pipeline decoders you will get a preamble like this:

import Json.Decode
import Json.Encode
import Json.Decode.Pipeline


-- Required packages:
-- * elm/json
-- * NoRedInk/elm-json-decode-pipeline

Finally, there are two naming styles you can choose from for the functions: noun-based and verb-based. If you use nouns, you will get names like accountDecoder and encodedAccount versus decodeAccount and encodeAccount when using verbs. I am partial to noun function names for the reason that in functional programs, we are describing what the transformations of the data are, rather than how they are done.

4 Likes

Thanks for keeping this project alive, I think it is a good tool, specially when you start learning Elm. Personally, I name decoders xxxxDecoder and encoders encodeXxxx because in the case of the decoders you describe the work to be done but you need an additional decode call in order to get the work done, so you are actually creating the description of the work, AKA, decoder, while encoders are regular functions that transform an input into a Value.

2 Likes

I guess I’m unlikely to satisfy everyone’s preferences when it comes to naming functions.

I tend to view all pure functions as a description of what needs to be done, similar to decoders, so I prefer noun names for that reason, and also because otherwise I have to come up with largely pointless verb prefixes like “get” and “calc” and “generate”.

The nomenclature happens to be very confused. For example, why do we have view (noun) and Browser.element (noun) and List.singleton (noun) but also List.map (verb) and List.filter (verb)? I don’t see a rationale other than historical precedent.

1 Like

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.