Add a conditional branching combinator
- Vorherrschende Sprache
- JavaScript
- Sterne
- 3
- Forks
- 0
- PR-Merge-Kennzahlen
- Keine gemergten PRs in 30 T.
Beschreibung
Elm provides `andThen : (a -> Decoder b) -> Decoder a -> Decoder b` function to create decoders that depend on previous results. For example if you are creating versioned data, you might do something like this:
```elm
info : Decoder Info
info =
field "version" int
|> andThen infoHelp
infoHelp : Int -> Decoder Info
infoHelp version =
case version of
4 ->
infoDecoder4
3 ->
infoDecoder3
_ ->
fail <|
"Trying to decode info, but version "
++ toString version ++ " is not supported."
-- infoDecoder4 : Decoder Info
-- infoDecoder3 : Decoder Info
```
decoder.flow does not provide `andThen` as it would make serialization and transfer of decoders across the threads impossible. Although similar to how `Decoder.record` and `Decoder.form` provide a way to address same use cases as `map`, `map2`, ...`map8` in Elm we could provide some solution to addressing `andThen` use cases like the one above. For instance `match` like combinator could be implemented:
```js
const version = Decoder.field("version", Decoder.Integer)
Decoder.either(
Decoder.when(version, Decoder.ok(4), infoDecoder4)
Decoder.when(version, Decoder.ok(3), infoDecoder3)
Decoder.error("Trying to decode info, but provided version isn't supported"))
```
Note that in comparison to `andThen` this is far more limited and even this example unlike original Elm code is unable to include encountered version in the error message, but it still might enable certain use cases that aren't possible today.
Primary limitation of this would be that unlike `andThen` result can't be carried over to the next decoder, but maybe that could be worked around like in the example below:
```js
const versionedInfo = Decoder.form({
version: Decoder.field("version", Decoder.Integer)
info: Decoder.value
})
const infoHelp = Decoder.either(
Decoder.record({ version: Decoder.ok(4), ok: infoDecoder4 }),
Decoder.record({ version: Decoder.ok(3), ok: infoDecoder3 }),
Decoder.record({ version: Decoder.Integer, error: Decoder.ok('Invalid version') }))
const info = Decoder.chain(versionedInfo, infoHelp)
```
P.S.: We currently have no `Decoder.value` nor `Decoder.chain` but they could be easily added.
Beitragsleitfaden
Für dieses Repository ist kein Beitragsleitfaden indexiert
Rechercherichtung
Beginne damit, die vorgeschlagenen Designs für Decoder.when, Decoder.either, Decoder.value und Decoder.chain mit dem bestehenden Verhalten von Decoder.record und Decoder.form zu vergleichen. Ermittle, welche Anwendungsfälle für bedingte Verzweigungen unterstützt werden können, ohne Decoder nicht mehr serialisierbar oder zwischen Threads übertragbar zu machen. Als abgeschlossen gilt dies, wenn eine abgestimmte API und ein abgestimmter Implementierungsumfang vorliegen, einschließlich des Umgangs mit ungültigen Versionen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- javascript
- Bereich
- data
- Issue-Typ
- Feature
- Schwierigkeit
- 5/5
- Geschätzter Aufwand
- Über eine Woche
- Aktivitätsstatus
- Veraltet
- Klarheit
- Muss geklärt werden
- Anfängerfreundlichkeit
- 25/100