如何在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 =
解码
函数,我不相信:=
中缀运算符仍然有效
第二个解决稍有不同的问题,即基于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
]