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 elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to