简体   繁体   English

Scala动态元组类型从序列构造

[英]Scala dynamic tuple type construction from sequence

I'm trying to generate some json using the json4s library which builds json using a dsl based around nested tuple structures. 我正在尝试使用json4s库生成一些json,该库使用基于嵌套元组结构的dsl构建json。 I have a scala Seq that I'd like to be able to convert to a nesting of tuples like so: 我有一个scala Seq ,我希望能够将其转换为像这样的元组嵌套:

// 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. 但是由于结果的类型现在被表示为Any ,即使实际类型正确,也不会触发(将其写入json的隐式转换)(并且在显式调用时抛出异常)。 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. 我知道scala支持递归类型,这似乎很合适,但是我无法理解在这种情况下如何使用它们,也不知道它们对于“真实”系统是否安全。

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: 您可以随时进行向JSON的转换,但是:

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 : 然后,您可以执行以下操作,因为json被静态地键入为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.) (作为一个脚注,有一种方法可以对元组进行折叠并以适当的静态类型结束,但是在这种情况下,这几乎肯定不是您想要的。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM