How does Json.decode concatenate a type?

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

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

Then I tried to create a Json Decoder in a separate module to decode this type:

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

The Elm compiler gives me an error in the map2 Bar line saying that the type Bar not found. The module containing the decoder has import Foo exposing (..) . I also tried to move this function to the same module that contains the type definition and get the same error, so it has nothing to do with being in a separate module.

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

What is the correct way to decode this type of join?

+5
source share
2 answers

Foo is a type. Bar is a constructor. Signature must be:

 barDecoder : Decoder Foo 

In addition, you will receive a compilation error on your current decoder. Let add an alias for the contents of the entry in Bar :

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

Your decoder might look like this:

 barDecoder : Decoder Foo barDecoder = Json.Decode.map Bar <| map2 BarContents (field "a" string) (field "b" string) 
+3
source

You should use Json.Decode.oneOf if you have several ways to decode json.

Here is an example of how you can use it. (I composed 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 (\xy -> 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 ] 
+7
source

Source: https://habr.com/ru/post/1263644/


All Articles