Decode a tuple using Json.Decode.andThen

93 Views Asked by At

Using Elm 0.19.1, I have the following two functions:

criteriaDecoder : List Field -> List Operator -> Int -> List (Cmd Msg) -> ( Decoder Criterion, List (Cmd Msg) )
criteriaDecoder fields operators currentDepth cmdsList =
    field "type" JD.string
        |> JD.andThen
            (\fieldType ->
                criterionDecoder fields operators currentDepth cmdsList fieldType
            )


criterionDecoder : List Field -> List Operator -> Int -> List (Cmd Msg) -> String -> ( Decoder Criterion, List (Cmd Msg) )
criterionDecoder fields operators currentDepth cmdsList criterionType =
    case criterionType of
        "condition" ->
            let
                ( decoder, cmds ) =
                    conditionDecoder fields operators cmdsList
            in
            ( JD.map Condition <| decoder, cmds )

        "conditionGroup" ->
            let
                ( decoder, cmds ) =
                    groupDecoder fields operators currentDepth cmdsList
            in
            ( JD.map CriterionGroup <| decoder, cmds )

        _ ->
            ( JD.fail <| "Could not decode criterion for type: " ++ criterionType, cmdsList)

Basically, it should get the value from field type from the JSON. This value must be used to determine the right decoder in criterionDecoder. Both functions must return a (Decoder Criterion, List ( Cmd Msg )) object.

The problem is as following: In the criteriaDecoder, I use the JD.andThen function to get the value of the field type. However, this will create a type mismatch. The JD.andThen function expects a Decoder object, while the criterionDecoder will return a tuple of a Decoder Criterion and a List ( Cmd Msg ). How can I solve this problem?

1

There are 1 best solutions below

1
bdukes On

You cannot return (Decoder Criterion, List ( Cmd Msg )) if the Cmd values depend on what's being decoded, because the Decoder has not run yet (i.e. it doesn't know which Cmd values to return until it's used to decode some value).

If the Cmd values that you're returning depend on the input to the decoder (which seems to be the case), those Cmd values will need to be an output of the decoder. So, instead of (Decoder Criterion, List ( Cmd Msg )), your decoder will also need to produce the Cmd values, Decoder (Criterion, List ( Cmd Msg )).