我如何Json.decode联合类型?

Cod*_*nis 5 json elm

我有一个像这样定义的类型module Foo exposing (..):

type Foo
    = Bar
        { a : String
        , b : String
        }
    | Baz
        ...
Run Code Online (Sandbox Code Playgroud)

然后我试图Json Decoder在一个单独的模块中创建一个解码这样的类型:

barDecoder : Decoder Bar
barDecoder =
    map2 Bar
        (field "a" string)
        (field "b" string)
Run Code Online (Sandbox Code Playgroud)

Elm编译器map2 Bar在行上给出了一个错误,指出Bar找不到类型.包含解码器的模块有import Foo exposing (..).我也尝试将此函数移动到包含类型定义的同一模块中并获得相同的错误,因此它与在单独的模块中没有任何关系.

我已经尝试过将其更改为map2 Foo.Bar,但这也无效.

解码这样的联合类型的正确方法是什么?

Tos*_*osh 10

Json.Decode.oneOf如果你有多种解码方式,你应该使用json.

以下是如何使用它的示例.(我弥补了,Baz因为你没有指明它.)

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 ]
Run Code Online (Sandbox Code Playgroud)


Cha*_*ert 3

Foo是类型。Bar是一个构造函数。签名应该是:

barDecoder : Decoder Foo
Run Code Online (Sandbox Code Playgroud)

此外,您将在当前的解码器上收到编译错误。让我们为 中的记录内容添加别名Bar

type alias BarContents =
    { a : String
    , b : String
    }

type Foo
    = Bar BarContents
    | Baz
Run Code Online (Sandbox Code Playgroud)

您的解码器可能如下所示:

barDecoder : Decoder Foo
barDecoder =
    Json.Decode.map Bar <|
         map2 BarContents
            (field "a" string)
            (field "b" string)
Run Code Online (Sandbox Code Playgroud)