[
    {
        "name": "Json.Decode.Extra",
        "comment": " Convenience functions for working with Json\n\n# Date\n@docs date\n\n# Incremental Decoding\n@docs apply, (|:)\n\n# List\n@docs sequence\n\n# Set\n@docs set\n\n# Dict\n@docs dict2\n\n# Maybe\n@docs withDefault, maybeNull\n\n# Recursively Defined Decoders\n@docs lazy\n\n",
        "unions": [],
        "aliases": [],
        "values": [
            {
                "name": "apply",
                "comment": " Can be helpful when decoding large objects incrementally.\n\n    import Date (Date)\n\n    type alias User =\n      { id                : Int\n      , createdAt         : Date\n      , updatedAt         : Date\n      , deletedAt         : Maybe Date\n      , username          : Maybe String\n      , email             : Maybe String\n      , fullname          : Maybe String\n      , avatar            : Maybe String\n      , isModerator       : Bool\n      , isOrganization    : Bool\n      , isAdmin           : Bool\n      }\n\n    metaDecoder : (Int -> Date -> Date -> Maybe Date -> b) -> Decoder b\n    metaDecoder f = f\n      `map`      (\"id\"        := int)\n      `apply` (\"createdAt\" := date)\n      `apply` (\"updatedAt\" := date)\n      `apply` (\"deletedAt\" := maybe date)\n\n    userDecoder : Decoder User\n    userDecoder = metaDecoder User\n      `apply` (\"username\"          := maybe string)\n      `apply` (\"email\"             := maybe string)\n      `apply` (\"fullname\"          := maybe string)\n      `apply` (\"avatar\"            := maybe string)\n      `apply` (\"isModerator\"       := bool)\n      `apply` (\"isOrganization\"    := bool)\n      `apply` (\"isAdmin\"           := bool)\n\nThis is a shortened form of\n\n    metaDecoder : (Int -> Date -> Date -> Maybe Date -> b) -> Decoder b\n    metaDecoder f = f\n      `map`      (\"id\"        := int)\n      `andThen` \\f -> f `map` (\"createdAt\" := date)\n      `andThen` \\f -> f `map` (\"updatedAt\" := date)\n      `andThen` \\f -> f `map` (\"deletedAt\" := maybe date)\n\n    userDecoder : Decoder User\n    userDecoder = metaDecoder User\n      `andThen` \\f -> f `map` (\"username\"          := maybe string)\n      `andThen` \\f -> f `map` (\"email\"             := maybe string)\n      `andThen` \\f -> f `map` (\"fullname\"          := maybe string)\n      `andThen` \\f -> f `map` (\"avatar\"            := maybe string)\n      `andThen` \\f -> f `map` (\"isModerator\"       := bool)\n      `andThen` \\f -> f `map` (\"isOrganization\"    := bool)\n      `andThen` \\f -> f `map` (\"isAdmin\"           := bool)\n\n",
                "type": "Decoder (a -> b) -> Decoder a -> Decoder b"
            },
            {
                "name": "date",
                "comment": " Extract a date using [`Date.fromString`](http://package.elm-lang.org/packages/elm-lang/core/latest/Date#fromString)\n",
                "type": "Decoder Date"
            },
            {
                "name": "dict2",
                "comment": " Extract a dict using separate decoders for keys and values.\n",
                "type": "Decoder comparable -> Decoder v -> Decoder (Dict comparable v)"
            },
            {
                "name": "lazy",
                "comment": " Enable decoders defined in terms of themselves by lazily creating them.\n\n    treeNode =\n      object2\n        instantiateTreeNode\n        (\"name\" := string)\n        (\"children\" := list (lazy (\\_ -> treeNode)))\n\n",
                "type": "(() -> Decoder a) -> Decoder a"
            },
            {
                "name": "maybeNull",
                "comment": " Extract a value that might be null. If the value is null,\nsucceed with Nothing. If the value is present but not null, succeed with\nJust that value. If the value is missing, fail.\n\n    -- Yields Nothing if middleName is null, and Just middleName if it's a string.\n    \"middleName\" := maybeNull string\n\n",
                "type": "Decoder a -> Decoder (Maybe a)"
            },
            {
                "name": "sequence",
                "comment": " This function turns a list of decoders into a decoder that returns a list.\n\nThe returned decoder will zip the list of decoders with a list of values, matching each decoder with exactly one value at the same position. This is most often useful in cases when you find yourself needing to dynamically generate a list of decoders based on some data, and decode some other data with this list of decoders. There are other functions that seem similar:\n\n- `Json.Decode.oneOf`, which will try every decoder for every value in the list, might be too lenient (e.g. a `4.0` will be interpreted as an `Int` just fine).\n- `Json.Decode.tuple1-8`, which do something similar, but have a hard-coded length. As opposed to these functions, where you can decode several different types and combine them, you'll need to manually unify all those types in one sum type to use `sequence`.\n\nNote that this function, unlike `List.map2`'s behaviour, expects the list of decoders to have the same length as the list of values in the JSON.\n\n    type FloatOrInt\n        = I Int\n        | F Float\n\n    -- we'd like a list like [I, F, I] from this\n    -- fairly contrived example, but data like this does exist!\n    json = \"[1, 2.0, 3]\"\n\n    intDecoder = Decode.map I Decode.int\n    floatDecoder = Decode.map F Decode.float\n\n    decoder : Decoder (List FloatOrInt)\n    decoder =\n        sequence [ intDecoder, floatDecoder, intDecoder ]\n\n    decoded = Decode.decodeString decoder json\n    -- Ok ([I 1,F 2,I 3]) : Result String (List FloatOrInt)\n\n",
                "type": "List (Decoder a) -> Decoder (List a)"
            },
            {
                "name": "set",
                "comment": " Extract a set.\n",
                "type": "Decoder comparable -> Decoder (Set comparable)"
            },
            {
                "name": "withDefault",
                "comment": " Try running the given decoder; if that fails, then succeed with the given\nfallback value.\n\n    -- If this field is missing or malformed, it will decode to [].\n    (\"optionalNames\" := list string)\n      |> (withDefault [])\n\n",
                "type": "a -> Decoder a -> Decoder a"
            }
        ],
        "binops": [
            {
                "name": "|:",
                "comment": " Infix version of `apply` that makes for a nice DSL when decoding objects:\n\n    locationDecoder : Decoder Location\n    locationDecoder =\n        succeed Location\n            |: (\"id\" := int)\n            |: (\"name\" := string)\n            |: (\"address\" := string)\n\n\n    type alias Location =\n        { id : Int\n        , name : String\n        , address : String\n        }\n\nIf you're curious, here's how this works behind the scenes.\n\n`Location` is a type alias, and type aliases give you a convenience function\nthat returns an instance of the record in question. Try this out in `elm repl`:\n\n    > type alias Location = { id : Int, name: String, address: String }\n\n    > Location\n    <function> : Int -> String -> String -> Repl.Location\n\n    > Location 1 \"The White House\" \"1600 Pennsylvania Ave\"\n    { id = 1, name = \"The White House\", address = \"1600 Pennsylvania Ave\" }\n\nIn other words, if you call the `Location` function, passing three arguments,\nit will return a new `Location` record by filling in each of its fields. (The\nargument order is based on the order in which we listed the fields in the\ntype alias; the first argument sets `id`, the second argument sets `name`, etc.)\n\nNow try running this through `elm repl`:\n\n    > import Json.Decode exposing (succeed, int, string, (:=))\n\n    > succeed Location\n    <function>\n        : Json.Decode.Decoder\n            (Int -> String -> String -> Repl.Location)\n\nSo `succeed Location` gives us a `Decoder (Int -> String -> String -> Location)`.\nThat's not what we want! What we want is a `Decoder Location`. All we have so\nfar is a `Decoder` that wraps not a `Location`, but rather a function that\nreturns a `Location`.\n\nWhat `|: (\"id\" := int)` does is to take that wrapped function and pass an\nargument to it.\n\n    > import Json.Decode exposing (succeed, int, string, (:=))\n\n    > (\"id\" := int)\n    <function> : Json.Decode.Decoder Int\n\n    > succeed Location |: (\"id\" := int)\n    <function>\n        : Json.Decode.Decoder\n            (String -> String -> Repl.Location)\n\nNotice how the wrapped function no longer takes an `Int` as its first argument.\nThat's because `|:` went ahead and supplied one: the `Int` wrapped by the decoder\n`(\"id\" := int)` (which returns a `Decoder Int`).\n\nCompare:\n\n    -- succeed Location\n    Decoder (Int -> String -> String -> Location)\n\n    -- succeed Location |: (\"id\" := int)\n    Decoder (String -> String -> Location)\n\nWe still want a `Decoder Location` and we still don't have it yet. Our decoder\nstill wraps a function instead of a plain `Location`. However, that function is\nnow smaller by one argument!\n\nLet's repeat this pattern to provide the first `String` argument next.\n\n    -- succeed Location\n    Decoder (Int -> String -> String -> Location)\n\n    -- succeed Location |: (\"id\" := int)\n    Decoder (String -> String -> Location)\n\n    -- succeed Location |: (\"id\" := int) |: (\"name\" := string)\n    Decoder (String -> Location)\n\nSmaller and smaller! Now we're down from `(Int -> String -> String -> Location)`\nto `(String -> Location)`. What happens if we repeat the pattern one more time?\n\n    -- succeed Location\n    Decoder (Int -> String -> String -> Location)\n\n    -- succeed Location |: (\"id\" := int)\n    Decoder (String -> String -> Location)\n\n    -- succeed Location |: (\"id\" := int) |: (\"name\" := string)\n    Decoder (String -> Location)\n\n    -- succeed Location |: (\"id\" := int) |: (\"name\" := string) |: (\"address\" := string)\n    Decoder Location\n\nHaving now supplied all three arguments to the wrapped function, it has ceased\nto be a function. It's now just a plain old `Location`, like we wanted all along.\n\nWe win!\n",
                "type": "Decoder (a -> b) -> Decoder a -> Decoder b",
                "associativity": "left",
                "precedence": 9
            }
        ]
    }
]