Elm 如何使用可选元素制作解码器?
我一直在使用一个解码器,它应该将数组Elm 如何使用可选元素制作解码器?,elm,decoder,Elm,Decoder,我一直在使用一个解码器,它应该将数组[9.34958,48.87733,1000]解码到点,其中索引2(高程)是可选的 type alias Point = { elev : Maybe Float , at : Float , lng : Float } 因此,我创建了以下解码器: fromArrayDecoder : Decoder Point fromArrayDecoder = map3 Point (index 2 Decode
[9.34958,48.87733,1000]
解码到点,其中索引2(高程)是可选的
type alias Point =
{ elev : Maybe Float
, at : Float
, lng : Float
}
因此,我创建了以下解码器:
fromArrayDecoder : Decoder Point
fromArrayDecoder =
map3 Point
(index 2 Decode.float |> Decode.maybe)
(index 1 Decode.float)
(index 0 Decode.float)
我现在的问题是,当索引2丢失或是字符串等任何类型时,解码器都会成功。但我只希望它在elev丢失时成功,而不是在它的类型错误时成功。有什么方法可以做到这一点吗?如果“缺少”的意思是值可以是null
,那么您可以使用而不是或者:
fromArrayDecoder : Decoder Point
fromArrayDecoder =
map3 Point
(index 2 Decode.float |> Decode.nullable)
(index 1 Decode.float)
(index 0 Decode.float)
如果是三元素数组或两元素数组,您可以按顺序使用多个解码器:
fromTwoArrayDecoder : Decoder Point
fromTwoArrayDecoder =
map3 (Point Nothing)
(index 1 Decode.float)
(index 0 Decode.float)
fromThreeArrayDecoder : Decoder Point
fromThreeArrayDecoder =
map3 Point
(index 2 Decode.float |> Decode.map Just)
(index 1 Decode.float)
(index 0 Decode.float)
fromArrayDecoder : Decoder Point
fromArrayDecoder =
oneOf
[ fromThreeArrayDecoder
, fromTwoArrayDecoder
]
请记住首先尝试3元素解码器,因为2元素解码器在3元素阵列上也会成功,但事实并非如此。我同意事实Json.Decode。也许在错误的值上给你什么都不给你,而不仅仅是一个缺少的值,这是令人惊讶的
可以按照您想要的方式工作,而不会太冗长
> d = Decode.succeed Point
| |> optional "2" (Decode.float |> Decode.map Just) Nothing
| |> required "1" Decode.float
| |> required "0" Decode.float
|
> "[1, 2, \"3\"]" |> Decode.decodeString d
Err (Failure ("Json.Decode.oneOf failed in the following 2 ways:\n\n\n\n(1) Problem with the given value:\n \n \"3\"\n \n Expecting a FLOAT\n\n\n\n(2) Problem with the given value:\n \n \"3\"\n \n Expecting null") <internals>)
: Result Decode.Error Point
> "[1, 2, 3]" |> Decode.decodeString d
Ok { at = 2, elev = Just 3, lng = 1 }
: Result Decode.Error Point
> "[1, 2]" |> Decode.decodeString d
Ok { at = 2, elev = Nothing, lng = 1 }
: Result Decode.Error Point
请注意,您仍然必须避免使用Json.Decode.maybe
。可能很容易编写可选的“2”(Decode.maybe Decode.float)而不编写任何内容
,这将导致与您最初得到的行为相同。您所说的“缺失”是什么意思?是null
,还是在这种情况下数组只有两个元素?
> "[0]" |> Decode.decodeString (Decode.field "0" Decode.int)
Ok 0 : Result Decode.Error Int
> "[]" |> Decode.decodeString (Decode.field "0" Decode.int)
Err (Failure ("Expecting an OBJECT with a field named `0`") <internals>)
: Result Decode.Error Int
> "[]" |> Decode.decodeString (Decode.index 0 Decode.int)
Err (Failure ("Expecting a LONGER array. Need index 0 but only see 0 entries") <internals>)