Closed MartinPotier closed 6 years ago
Sum types are indeed supported. It needs two arguments because of the lack of typeclasses in Elm. The arguments are the decoders for the a
and b
types!
Still, the implementation of jsonDecEither
/jsonEncEither
is on me, right? I have to provide a way to choose what encoder to use.
Example:
The right side of (:=) is causing a type mismatch.
207| "someConfigField" := jsonDecEither (Json.Decode.string) (jsonDecValue)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(:=) is expecting the right side to be a:
Json.Decode.Decoder a
But the right side is:
Json.Decode.Value -> Either String Json.Decode.Value
Hint: It looks like a function needs 1 more argument.
Yeah, my right side should be an Either String Json.Decode.Value
. Or should I wrap this in a Decoder
?
jsonEncEither leftEnc rightEnc v =
case v of
Left e -> leftEnc e
Right o -> rightEnc o
jsonDecEither leftDec rightDec v =
Json.Decode.success <|
case (Json.Decode.decodeValue leftDec v) of
Ok s -> Left s
Err _ -> case (Json.Decode.decodeValue rightDec v) of
Ok v -> Right v
Err _ -> Left ""
The encoder part is OK because I can pattern match, but the decoder part is trickier, since I'm not allowed to peek and decide what constructor to use. The decoder I wrote here is wrong of course. But this may give you an idea of what I am trying to do.
But it really depends on how you encoded your sum type! What is its shape, in json, for both the left and right cases? Also, would it be generic (can you encode Either String String
) ?
Hmm, you are right, I should look into the encoding of the sum type. It was automatically derived using generics.
EDIT:
Ok, new approach that may or may not work, using map
. At least it passes the type checking (I'm using oneOf
):
jsonEncEither leftEnc rightEnc v =
case v of
Left e -> leftEnc e
Right o -> rightEnc o
jsonDecEither : Json.Decode.Decoder a -> Json.Decode.Decoder b -> Json.Decode.Decoder (Either a b)
jsonDecEither leftDec rightDec =
let liftLeftDec = Json.Decode.map Left leftDec
liftRightDec = Json.Decode.map Right rightDec
in
Json.Decode.oneOf [ liftLeftDec, liftRightDec ]
It all depends on the behaviour of oneOf
. And of course Either String String
is quite undefined here. It may always pick up a Left
value…
Closing this for now, as it may not be a problem of elm-bridge.
Just a note : you will usually need a tag of some sort for your encoding to be generic. For example, this could be decoded as List (Either String String)
:
[{"left":"bar"}, {"right":"foo"}]
Hi,
I'm trying to convert my Haskell
Either a b
to an ElmEither a b
but the encoder and decoder for this are… weird. It creates jsonDecEither and jsonEncEither decoders that need 2 arguments! I'd expect a set of encoder/decoder per constructor. Are sum types supported?Nice job by the way, for all the rest it's been working like a charm!