Reputation: 15810
Scala's Either[A, B]
type is a type that's either A
or B
.
Is there a generalization that lets me define something like the following?
type JSON = Either[String, Int, Float, List[JSON], Map[String, JSON]]
Upvotes: 3
Views: 1122
Reputation: 66422
Even if you defined your own FiveWay
type (an "Either
" that would take five type parameters), Scala would not allow you to define
type Json = FiveWay[String, Int, Float, List[Json], Map[String, Json]]
Why? Because a type alias (Json
, here) cannot appear on the right-hand side of its own definition.
The following example illustrates this fact:
scala> type Json = Either[String, Json]
<console>:11: error: illegal cyclic reference involving type Json
type Json = Either[String, Json]
More precisely, the Scala specification (section 4.3) tells us that
the type
T
in a type aliastype t[tps] = T
may not refer directly or indirectly to the namet
What you want to do here, instead, is apply the Algebraic-Data-Type pattern:
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
Upvotes: 6
Reputation: 30756
The typical approach would be to use a sealed trait with final subtypes.
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
The feature overview of Shapeless says
shapeless has a Coproduct type, a generalization of Scala's
Either
to an arbitrary number of choices.
So my first thought would be to try this...
type JSON = String :+: Int :+: Float :+: List[JSON] :+: Map[String, JSON]
... but unfortunately the cyclic reference to JSON
doesn't work. And I think this is the problem you're going to run into with any approach you try.
David Barri suggests an approach involving the "cake pattern", though I don't think it's helpful here.
Upvotes: 8