Hi all,

I've been struggling with this for the better part of today. I find Json 
decoders really hard to grasp, for some reason, especially when there's a 
weird mapping you need to do. My JSON looks like this, and is an abstract 
syntax tree of "select * from submissions where age < 10":

{
    "0": {
        "0": "select",
        "1": [],
        "2": {
            "type": "SelectList"
        },
        "3": {
            "0": {
                "0": "from",
                "1": [
                    {
                        "0": "submissions",
                        "1": null,
                        "2": null,
                        "3": null,
                        "4": null,
                        "5": null,
                        "type": "TablePrimary_table_or_query_name"
                    }
                ],
                "type": "FromClause"
            },
            "1": {
                "0": "where",
                "1": {
                    "0": null,
                    "1": {
                        "0": [
                            "age"
                        ],
                        "1": {
                            "0": "<",
                            "1": "10",
                            "type": "ComparisonPredicatePart2"
                        },
                        "type": "ComparisonPredicate"
                    },
                    "type": "BooleanFactor"
                },
                "type": "WhereClause"
            },
            "2": null,
            "3": null,
            "type": "TableExpression"
        },
        "type": "QuerySpecification"
    },
    "1": null,
    "2": null,
    "type": "CursorSpecification"
}

I'd like to be able decode it into a node union type and type alias:

type Node =
    Empty
  | Node NodeRecord


type alias NodeRecord = {
    type' : String
  , primitiveValue: Maybe String
  , children : List Node
  }

Now, because each child of the node is listed as a key-value pair in the 
node itself, I'm not sure how to write the decoder so that each of the 
key-value pairs except "type" are mapped into `children` field of the 
NodeRecord. At the end of post, that code was the best I could come up 
with, but I get an error:

"TypeError: Cannot read property 'tag' of undefined".
function runHelp(decoder, value)
{
switch (decoder.tag) <-------- this is where it fails.
{
case 'bool':
return (typeof value === 'boolean')
? ok(value)
: badPrimitive('a Bool', value);

case 'int':
if (typeof value !== 'number') {
return badPrimitive('an Int', value);
....

I'm not sure how to debug this, or whether I'm going down the right path. 
Below is the decoder code I have. Can anyone give me a hint? Thanks.

nodeDecoder : Decoder Node
nodeDecoder =
  oneOf [
    null Empty
  , string `andThen` primitiveNodeDecoder
  , parentNodeDecoder
  ]

primitiveNodeDecoder : String -> Decoder Node
primitiveNodeDecoder primitive =
  object3 fromFields
    (succeed "primitive")
    (maybe (succeed primitive))
    (succeed [])

parentNodeDecoder : Decoder Node
parentNodeDecoder =
  object3 fromFields
    ("type" := string)
    (maybe ("primitiveValue" := string))
    ("children" := childrenDecoder)

childrenDecoder : Decoder (List Node)
childrenDecoder =
  customDecoder (dict value) (\nodeDict ->
    let
      children = nodeDict |> Dict.remove "type" |> Dict.values
      b = Debug.log "children" children
      combineResults = List.foldr (Result.map2 (::)) (Ok [])
      childDecoder = lazy (\_ -> nodeDecoder)
      results = combineResults (List.map (decodeValue childDecoder) 
children)
      c = Debug.log "results" results
    in
      results

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to