2016-04-14 4 views

Antwort

8

Der typische Ansatz wäre, eine versiegelte Eigenschaft mit endgültigen Subtypen zu verwenden.

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 

Die feature overview of Shapeless sagt

formlos einen Co-Produkt-Typen hat, eine Verallgemeinerung von Scala Either auf eine beliebige Anzahl von Möglichkeiten.

Also mein erster Gedanke wäre, dies zu versuchen ...

type JSON = String :+: Int :+: Float :+: List[JSON] :+: Map[String, JSON] 

... aber leider ist die zyklische Bezug auf JSON funktioniert nicht. Und ich denke, das ist das Problem, mit dem Sie bei jedem Versuch, den Sie versuchen, konfrontiert werden.


David Barri schlägt einen Ansatz der „Kuchen-Muster“ beteiligt, obwohl ich nicht glaube, es ist hier hilfreich.

+0

Noch müssen zugeben, scalaz hat 'Entweder3', obwohl Ihre Antwort definitiv zu gehen. – chuwy

6

Auch wenn Sie Ihre eigene FiveWay Typ definiert (ein „Either“, die fünf Parameter des Typs nehmen würde), Scala würden Sie nicht zulassen, dass

type Json = FiveWay[String, Int, Float, List[Json], Map[String, Json]] 

Warum definieren? Weil ein Typ-Alias ​​(Json, hier) nicht auf der rechten Seite seiner eigenen Definition erscheinen kann. Das folgende Beispiel diese Tatsache zeigt:

scala> type Json = Either[String, Json] 
<console>:11: error: illegal cyclic reference involving type Json 
     type Json = Either[String, Json] 

Genauer gesagt, die Scala-Spezifikation (section 4.3) sagt uns, dass

der Typ T in einem Typ alias type t[tps] = T nicht direkt oder indirekt mit dem Namen beziehen t

Was Sie hier, stattdessen tun wollen, ist die algebraische-Data-Type Muster gelten:

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 
Verwandte Themen