如何在elm 0.19中将Json.decode.Value解码为标记的联合类型?

如何在elm 0.19中将Json.decode.Value解码为标记的联合类型?,json,functional-programming,elm,decoder,Json,Functional Programming,Elm,Decoder,我明白了 我认为第一个与elm 0.19无关。我在中找不到解码函数,我不相信:=中缀运算符仍然有效 第二个解决稍有不同的问题,即基于JSON字段的值进行有条件解码 如果我有通过端口发送的数据和以下类型: 导入Json.Decode(解码器、映射、其中之一、字符串、成功,然后是map2、map4) 如何为标记的联合类型状态编写解码器,以解码从端口返回的数据 到目前为止,我得到的最好结果是 statusDecoder : Decoder Status statusDecoder =

我明白了

我认为第一个与elm 0.19无关。我在中找不到
解码
函数,我不相信
:=
中缀运算符仍然有效

第二个解决稍有不同的问题,即基于JSON字段的值进行有条件解码

如果我有通过端口发送的数据和以下类型:

导入Json.Decode(解码器、映射、其中之一、字符串、成功,然后是map2、map4)

如何为标记的联合类型
状态
编写解码器,以解码从端口返回的数据

到目前为止,我得到的最好结果是

statusDecoder : Decoder Status
statusDecoder =
    oneOf
        [ dataDecoder andThen (\data -> succeed (Authenticated data)
        , errorDecoder andThen (\error -> succeed (Unauthenticated (Just error)))
        ]
哪个是无效的,或者

getStatus : Json.Decode.Value -> Status
getStatus value =
    let
        decodedData =
            decodeValue dataDecoder value
    in
    case decodedData of
        Ok data ->
            Authenticated data

        Err _ ->
            let
                decodedError =
                    decodeValue errorDecoder value
            in
            case decodedError of
                Ok error ->
                    Unauthenticated (Just error)

                Err err ->
                    Unauthenticated (Just { error = "There was a problem decoding the JSON", errorDescription = "" })

这真的很难看而且感觉不对劲。

你已经完成了所有的艰苦工作。这就是你现在所需要的。注意
.map
是处理案例陈述的快速方法

import Json.Decode as Decode exposing (Decoder)
statusDecoder =
    Decode.oneOf
        [ Decode.map Authenticated dataDecoder
        , Decode.map Unauthenticated <| Decode.maybe errorDecoder
        ]
import Json.Decode as Decode exposing(解码器)
状态解码器=
破译
[Decode.map经过身份验证的数据解码器

,Decode.map Unauthenticated我使用的解决方案是使用
Status
类型构造函数
Authenticated Data
Unauthenticated make Error
解码器数据和
解码器错误
类型转换为
解码器状态
类型

然后,我可以使用该函数根据数据的形状将其解码为一个或另一个,因为两个解码器现在都是相同类型的
解码器状态

dataDecoder : Decoder Status
dataDecoder =
    map Authenticated <|
        map4 Data
            (field "accessToken" string)
            (field "email" string)
            (field "name" string)
            (field "nickname" string)


errorDecoder : Decoder Status
errorDecoder =
    map Unauthenticated <|
        maybe <|
            map2 Error
                (field "error" string)
                (field "errorDescription" string)


statusDecoder : Decoder Status
statusDecoder =
    oneOf [ dataDecoder, errorDecoder ]
dataDecoder : Decoder Status
dataDecoder =
    map Authenticated <|
        map4 Data
            (field "accessToken" string)
            (field "email" string)
            (field "name" string)
            (field "nickname" string)


errorDecoder : Decoder Status
errorDecoder =
    map Unauthenticated <|
        maybe <|
            map2 Error
                (field "error" string)
                (field "errorDescription" string)


statusDecoder : Decoder Status
statusDecoder =
    oneOf [ dataDecoder, errorDecoder ]
-- UPDATE

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ReceiveLoginResponse response ->
            let
                decodedResponse = decodeValue Auth.statusDecoder response
            in
            case decodedResponse of
                Ok status ->
                    ( { model
                        | authStatus = status 
                      }
                      , Cmd.none
                    )
         ...

-- SUBSCRIPTIONS


subscriptions : Model -> Sub Msg
subscriptions model =
    Sub.batch
        [ loginResponse ReceiveLoginResponse
        ]