Gizra / elm-compat-019 / Json.Decode017

There were quite a few changes between Elm 0.17 and 0.18 in Json.Decode. Here are some things from Elm 0.17.

andThen : Json.Decode.Decoder a -> (a -> Json.Decode.Decoder b) -> Json.Decode.Decoder b

Helpful when a field tells you about the overall structure of the JSON you are dealing with. For example, imagine we are getting JSON representing different shapes. Data like this:

{ "tag": "rectangle", "width": 2, "height": 3 }
{ "tag": "circle", "radius": 2 }

The following shape decoder looks at the tag to know what other fields to expect and then it extracts the relevant information.

type Shape
    = Rectangle Float Float
    | Circle Float

shape : Decoder Shape
shape =
    field "tag" string `andThen` shapeInfo

shapeInfo : String -> Decoder Shape
shapeInfo tag =
    case tag of
        "rectangle" ->
            object2 Rectangle (field "width" float) (field "height" float)

        "circle" ->
            object1 Circle (field "radius" float)

        _ ->
            fail (tag ++ " is not a recognized tag for shapes")

customDecoder : Json.Decode.Decoder a -> (a -> Result String b) -> Json.Decode.Decoder b

Create a custom decoder that may do some fancy computation.

object1 : (a -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder value

Apply a function to a decoder. You can use this function as map if you must (which can be done with any objectN function actually).

object1 sqrt (field "x" float)

object2 : (a -> b -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder value

Use two different decoders on a JS value. This is nice for extracting multiple fields from an object.

point : Decoder ( Float, Float )
point =
    object2 (\a b -> ( a, b ))
        (field "x" float)
        (field "y" float)

object3 : (a -> b -> c -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder value

Use three different decoders on a JS value. This is nice for extracting multiple fields from an object.

type alias Job =
    { name : String, id : Int, completed : Bool }

job : Decoder Job
job =
    object3 Job
        (field "name" string)
        (field "id" int)
        (field "completed" bool)

object4 : (a -> b -> c -> d -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder value

object5 : (a -> b -> c -> d -> e -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder value

object6 : (a -> b -> c -> d -> e -> f -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder f -> Json.Decode.Decoder value

object7 : (a -> b -> c -> d -> e -> f -> g -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder f -> Json.Decode.Decoder g -> Json.Decode.Decoder value

object8 : (a -> b -> c -> d -> e -> f -> g -> h -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder f -> Json.Decode.Decoder g -> Json.Decode.Decoder h -> Json.Decode.Decoder value

tuple1 : (a -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder value

Handle an array with exactly one element.

extractString : Decoder String
extractString =
    tuple1 identity string

authorship : Decoder String
authorship =
    oneOf
        [ tuple1 (\author -> "Author: " ++ author) string
        , list string |> map (\authors -> "Co-authors: " ++ String.join ", " authors)
        ]

tuple2 : (a -> b -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder value

Handle an array with exactly two elements. Useful for points and simple pairs.

point : Decoder ( Float, Float )
point =
    tuple2 (\a b -> ( a, b )) float float


-- ["John","Doe"] or ["Hermann","Hesse"]
name : Decoder Name
name =
    tuple2 Name string string

type alias Name =
    { first : String, last : String }

tuple3 : (a -> b -> c -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder value

Handle an array with exactly three elements.

point3D : Decoder ( Float, Float, Float )
point3D =
    tuple3 (\a b c -> ( a, b, c )) float float float

tuple4 : (a -> b -> c -> d -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder value

tuple5 : (a -> b -> c -> d -> e -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder value

tuple6 : (a -> b -> c -> d -> e -> f -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder f -> Json.Decode.Decoder value

tuple7 : (a -> b -> c -> d -> e -> f -> g -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder f -> Json.Decode.Decoder g -> Json.Decode.Decoder value

tuple8 : (a -> b -> c -> d -> e -> f -> g -> h -> value) -> Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder c -> Json.Decode.Decoder d -> Json.Decode.Decoder e -> Json.Decode.Decoder f -> Json.Decode.Decoder g -> Json.Decode.Decoder h -> Json.Decode.Decoder value