Skip to content

Instantly share code, notes, and snippets.

@jhrcek
Last active June 9, 2017 09:57
Show Gist options
  • Save jhrcek/b00f0f59f11d63f3635c730587579561 to your computer and use it in GitHub Desktop.
Save jhrcek/b00f0f59f11d63f3635c730587579561 to your computer and use it in GitHub Desktop.
How to remove union type parsing boilerplate?
---- BOILER-PLATEY version I'd like to make more succint - I've got 15 simple union types like this and don't want to declare decoder for each of them like this..
type Severity
= INFO
| WARN
| ERROR
decodeSeverity : Decoder Severity
decodeSeverity =
Decode.string
|> Decode.andThen
(\str ->
case str of
"INFO" ->
Decode.succeed INFO
"WARN" ->
Decode.succeed WARN
"ERROR" ->
Decode.succeed ERROR
_ ->
Decode.fail <| "Unexpected severity '" ++ str ++ "' - expected one of INFO/WARN/ERROR"
)
---- Attempt at improvement by extracting the common pattern
type Severity
= INFO
| WARN
| ERROR
severityDecoder : Decoder Severity
severityDecoder =
Decode.string |> Decode.andThen (makeUnionDecoder [ INFO, WARN, ERROR ])
makeUnionDecoder : List a -> String -> Decoder a
makeUnionDecoder values strToParse =
List.filter (\val -> toString val == strToParse) values
|> List.head
|> \maybeVal ->
case maybeVal of
Nothing ->
Decode.fail <| "Unexpected response type: '" ++ strToParse ++ "' - expected one of " ++ (toString values)
Just val ->
Decode.succeed val
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment