Reputation: 1311
I'm trying to generate some json using the json4s library which builds json using a dsl based around nested tuple structures. I have a scala Seq
that I'd like to be able to convert to a nesting of tuples like so:
// scala Seq
val s = Seq("a", "b", "c", "d")
val rootItem = "id" -> 1234
// desired json
{
"a" : {
"b" : {
"c" : {
"d" : {
"id" : 1234
}
}
}
}
}
If I force it to ignore the types I can produce the desired tuple structure as follows:
// yields ("a", ("b", ("c", ("d", ("id", 1234)))))
s.foldRight[Any](rootItem)(_ -> _)
but because the type of the result is now denoted as Any
the implicit conversion that write this to json don't fire (and throw an exception when called explicitly) despite the actual type being correct. I'm at a loss for how to construct this datastructure in a typesafe way. Ideally I'd like a solution that is able to appropriately build up the type, though I understand that it might be impossible since it requires information only available at runtime (the length of the list). I know that scala supports recursive types, which seem to potentially fit the bill but I haven't been able to understand how to work them in this case and don't know if they are safe for a 'real' system.
Upvotes: 1
Views: 1003
Reputation: 139028
You're not going to be able to do this with a plain old fold, since the accumulator has to be the same type the whole time.
You can make the transformation to JSON as you go, however:
val s = Seq("a", "b", "c", "d")
val rootItem = "id" -> 1234
import org.json4s._
import org.json4s.JsonDSL._
import org.json4s.jackson.JsonMethods._
val json = s.foldRight[JObject](rootItem)(_ -> _)
And then you can do the following, since json
is statically typed as a JObject
:
scala> pretty(render(json))
res0: String =
{
"a" : {
"b" : {
"c" : {
"d" : {
"id" : 1234
}
}
}
}
}
(As a footnote, there is a way you could do the fold with tuples and end up with the appropriate static type, but that's almost certainly not what you want in this case.)
Upvotes: 1