Suggestions for creating a Scalaz Tree out of a polymorphic set of Nodes in a JSON tree

65 views Asked by At

I have previously used C++ with tools like Antlr to read a DSL and convert it into an AST/symbol table and then used tree walkers to create object models which were then elaborated and then the resulting data structure was generated into yet another language(s).

I know how to traverse/transform Scala trees and graphs many different ways. I am struggling with how to create a JSON parser that will create a Tree in an elegant way.

I could use Circe to parse the JSON and then read the Circe data structure and check the type of each node during the traversal and create the corresponding case class object.I am wondering if there is a simpler way.

Using JSON to describe a high level specification of a tree with polymorphic nodes as follows what Scala libraries can convert the JSON into a Scala Tree?

The tree will be edited and nodes will be added, deleted, and moved to create a new immutable data structure.

I have looked at Scalaz but it may not be appropriate since there are different node types and I am not sure how to go directly from JSON to a Scalaz Tree.

Tree https://scalaz.github.io/scalaz/scalaz-2.9.1-6.0.4/doc.sxr/scalaz/Tree.scala.html#40955

Example: https://scalaz.github.io/scalaz/scalaz-2.9.1-6.0.4/doc.sxr/scalaz/example/ExampleTree.scala.html

object ExampleTree {
  def main(args: Array[String]) = run

  import Scalaz._

  def run {
    val tree: Tree[Int] =
    1.node(
      2.leaf,
      3.node(
        4.leaf))

This link Traverse tree in a functional way has an example of a Tree constructed using the same node type. See below.

package main

import scala.collection.mutable.ListBuffer

sealed trait Tree[Node] {

  val node: Node

  val parent: Option[Tree[Node]]

  val children: ListBuffer[Tree[Node]]

  def add(n: Node): Tree[Node]

  def size: Int

  def getOpt(p: (Node) => Boolean): Option[Tree[Node]]

  override def toString = {
    s"""[$node${if (children.isEmpty) "" else s", Children: $children"}]"""
  }
}

case class ConcreteTree(override val node: Int) extends Tree[Int] {

  override val children = ListBuffer[Tree[Int]]()

  override val parent: Option[Tree[Int]] = None

  override def add(n: Int): ConcreteTree = {
    val newNode = new ConcreteTree(n) {override val parent: Option[Tree[Int]] = Some(this)}
    children += newNode
    newNode
  }
}

What I am asking is for a Scala way to convert the polymorphic JSON into a Tree structure.

Each Node type in the tree has a corresponding case class. The JSON needs to be parsed, the type matched and correct case class used for the JSON type.

If you feel that this question some how violates the policies on StackOverflow rather than giving it a minus point perhaps you can leave a comment with a suggestion(s) about how to change the question to comply with the StackOverflow rules.

Example JSON:

{
  "root": {
    "Container": {
      "attributes": [],
      "children": {
        "Container": {
          "attributes": [],
          "children": {
            "Container": {
              "attributes": [],
              "children": {
                "circle": {
                  "fill": "blue",
                  "diameter": "4"
                }
              }
            },
            "square": {
              "name": "Y",
              "color": "red",
              "length": "10",
              "width": "4"
            }
          }
        }
      }
    }
  }
}
0

There are 0 answers