Scala的Either[A, B]
类型是A
或B
类型。
是否存在允许我定义类似以下内容的概括?
type JSON = Either[String, Int, Float, List[JSON], Map[String, JSON]]
答案 0 :(得分:8)
典型的方法是使用具有最终亚型的密封性状。
sealed trait JSON
final case class StringJSON(x: String) extends JSON
final case class IntJSON(x: Int) extends JSON
final case class FloatJSON(x: Float) extends JSON
final case class ListJSON(x: List[JSON]) extends JSON
final case class MapJSON(x: Map[String, JSON]) extends JSON
feature overview of Shapeless说
shapeless有一个Coproduct类型,Scala的
Either
概括为任意数量的选择。
所以我的第一个想法是尝试这个......
type JSON = String :+: Int :+: Float :+: List[JSON] :+: Map[String, JSON]
...但遗憾的是,对JSON
的循环引用不起作用。而且我认为这是你尝试的任何方法都会遇到的问题。
David Barri提出了一种涉及“蛋糕模式”的方法,尽管我认为这在这里没有用。
答案 1 :(得分:6)
即使您定义了自己的FiveWay
类型(" Either
"它将采用五种类型参数),Scala也不允许您定义
type Json = FiveWay[String, Int, Float, List[Json], Map[String, Json]]
为什么呢?因为类型别名(Json
,此处)不能出现在其自己定义的右侧。
以下示例说明了这一事实:
scala> type Json = Either[String, Json]
<console>:11: error: illegal cyclic reference involving type Json
type Json = Either[String, Json]
更准确地说,Scala规范(section 4.3)告诉我们
类型别名
T
中的type t[tps] = T
类型可能无法直接或间接引用名称t
您要在此处执行的操作是应用代数数据类型模式:
sealed trait Json
final case class JsonString(string: String) extends Json
final case class JsonInt(int: Int) extends Json
final case class JsonFloat(float: Float) extends Json
final case class JsonArray(list: List[Json]) extends Json
final case class JsonObject(map: Map[String, Json]) extends Json