Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I Json.decode a union type?

Tags:

json

elm

I have a type defined like this inside module Foo exposing (..):

type Foo
    = Bar
        { a : String
        , b : String
        }
    | Baz
        ...

Then I've tried to create a Json Decoder in a separate module to decode that type like this:

barDecoder : Decoder Bar
barDecoder =
    map2 Bar
        (field "a" string)
        (field "b" string)

The Elm compiler gives me an error on the map2 Bar line saying that type Bar is not found. The module that contains the decoder has import Foo exposing (..). I also tried moving this function into the same module that contains the type definition and get the same error, so it doesn't have anything to do with being in a separate module.

I've tried changing it to map2 Foo.Bar, but that didn't work either.

What's the right way to decode a union type like this?

like image 396
CoderDennis Avatar asked Jan 31 '17 23:01

CoderDennis


Video Answer


1 Answers

You should use Json.Decode.oneOf if you have multiple way of decoding json.

Here is example how you can use it. (I made up Baz because you did not specify it.)

import Json.Decode as Json

type Foo
    = Bar
        { a : String
        , b : String
        }
    | Baz Int


barDecoder : Json.Decoder Foo
barDecoder =
    Json.map2 (\x y -> Bar { a = x, b = y })
        (Json.field "a" Json.string)
        (Json.field "b" Json.string)


bazDecoder : Json.Decoder Foo
bazDecoder =
    Json.map Baz Json.int


fooDecoder : Json.Decoder Foo
fooDecoder =
    Json.oneOf [ barDecoder, bazDecoder ]
like image 74
Tosh Avatar answered Oct 06 '22 18:10

Tosh