Search code examples
jsonnested-listselm

Decoding a nested list (list of lists with arbitrary depth) recursively


Consider this recursive type definition:

type NestedList a
    = Elem a
    | SubList (List (NestedList a))

How can I write a decoder in order to decode a JSON list (e.g [1, [[2, [3, 4]], 5], 6, [7, 8, 9]]) into the NestedList type:

SubList
    [ Elem 1
    , SubList [ SubList [ Elem 2, SubList [ Elem 3, Elem 4 ] ], Elem 5 ]
    , Elem 6
    , SubList [ Elem 7, Elem 8, Elem 9 ]
    ]

Solution

  • It can be done recursively, using Json.Decode.oneOf and Json.Decode.lazy. The decoder for a nested list of integers looks like this:

    import Json.Decode as Decode exposing (Decoder)
    
    nestedListDecoder : Decoder (NestedList Int)
    nestedListDecoder =
        Decode.oneOf
            [ Decode.int |> Decode.map Elem
            , Decode.list (Decode.lazy (\_ -> nestedListDecoder)) |> Decode.map SubList
            ]