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

时间:2014-06-21 17:52:41

标签: scala types

我尝试使用json4s库生成一些json,该库使用基于嵌套元组结构的dsl构建json。我有一个scala Seq,我希望能够像这样转换为一组元组:

// scala Seq
val s = Seq("a", "b", "c", "d")
val rootItem = "id" -> 1234
// desired json
{
  "a" : {
    "b" : {
      "c" : {
        "d" : {
          "id" : 1234
        }
      }
    }
  }
}

如果我强制它忽略类型,我可以产生所需的元组结构,如下所示:

// yields ("a", ("b", ("c", ("d", ("id", 1234)))))
s.foldRight[Any](rootItem)(_ -> _) 

但是因为结果的类型现在表示为Any,将此写入json的隐式转换不会触发(并在显式调用时抛出异常),尽管实际类型是正确的。我对如何以类型安全的方式构建这种数据结构感到茫然。理想情况下,我喜欢能够正确构建类型的解决方案,但我知道它可能是不可能的,因为它需要仅在运行时可用的信息(列表的长度)。我知道scala支持递归类型,这似乎可能符合要求,但我还没有能够理解如何在这种情况下使用它们,并且不知道它们是否安全。真正的'系统

1 个答案:

答案 0 :(得分:1)

你不能用普通的旧折叠来做这件事,因为累加器必须是整个时间的相同类型。

但是,您可以随时转换为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)(_ -> _)

然后您可以执行以下操作,因为json被静态输入为JObject

scala> pretty(render(json))
res0: String = 
{
  "a" : {
    "b" : {
      "c" : {
        "d" : {
          "id" : 1234
        }
      }
    }
  }
}

(作为一个脚注,有a way你可以用元组进行折叠,最后得到适当的静态类型,但在这种情况下几乎肯定不是你想要的。)