Gozala / Gozala/decoder.flow

Add a conditional branching combinator

Abierto
#2 5 comentarios 2 reacciones 0 asignados Ver en GitHub
Lenguaje dominante
JavaScript
Estrellas
3
Forks
0
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

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.

Guía de contribución

No hay ninguna guía de contribución indexada para este repositorio

Línea de trabajo

Comienza comparando los diseños propuestos de Decoder.when, Decoder.either, Decoder.value y Decoder.chain con el comportamiento existente de Decoder.record y Decoder.form. Determina qué casos de uso de ramificación condicional se pueden admitir sin hacer que los decodificadores sean imposibles de serializar o transferir entre hilos. Se considera completado cuando exista un acuerdo sobre la API y el alcance de la implementación, incluido cómo se gestionan las versiones no válidas.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
javascript
Área
data
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Necesita aclaración
Aptitud para principiantes
25/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.