1

Wie kann ich diese rekursive Grammatik mit Typ-Aliasnamen beschreiben:mit Aliase Typ rekursive Grammatik Beschreiben

type FieldValue = Seq[String] :+: String :+: Int :+: Long :+: CNil 
type FieldLeaf = FieldValue :+: SubField :+: CNil 
type SubField = Seq[Field] 
type Field = (String, FieldLeaf) 

Wie es gibt mir steht, die Scala-Compiler (2.12.1):

Error:(14, 25) illegal cyclic reference involving type FieldLeaf 
    type Field = (String, FieldLeaf) 

PS Der Kontext dazu ist das Parsen einer rekursiven Grammatik mit fastparse.


Edit (als Antwort auf @ OlivierBlanvillain Antwort unten)

Diese Antwort war wirklich eine Sache der Schönheit und genau das, was ich suchte, ich werde es für die Zukunft erinnern.

jedoch aus anderen Gründen, in diesem speziellen Fall hatte ich stattdessen mit diesen Definitionen zu gehen:

case class Field(name: String, leaf: FieldLeaf) 
    sealed trait FieldLeaf 
    sealed trait FieldValue extends FieldLeaf 
    case class StringsFieldValue(value: Seq[String]) extends FieldValue 
    case class StringFieldValue(value: String) extends FieldValue 
    case class IntFieldValue(value: Int) extends FieldValue 
    case class LongFieldValue(value: Long) extends FieldValue 
    case class SubField(value: Seq[Field]) extends FieldLeaf 

Siehe auch: Instantiate types from recursive type grammar

+0

Was ist 'CNil' und': +: '? – Rumid

+0

Vielleicht könnten Sie auch erklären, welche Struktur es haben sollte, vielleicht ist es ein Konstruktionsfehler. Die Beseitigung von 'type Subfield' und die Verwendung von' Seq [Field] 'sollte Ihr Problem lösen, aber vielleicht gibt es eine bessere Lösung zB das Erstellen zusätzlicher Klassen. – Rumid

+1

Sorry @Rumid, sollte die Importe enthalten haben. Ich habe sie aus Gründen der Kürze ausgeschlossen. Es ist formlos. – eirirlar

Antwort

2

Verwenden Sie einen Fixpunkt Typen. Zum Beispiel:

case class Fix[F[_]](out: F[Fix[F]]) 

Hier können Sie schreiben:

type FieldValue = Seq[String] :+: String :+: Int :+: Long :+: CNil 
type FieldLeaf[F] = FieldValue :+: SubField[F] :+: CNil 
type SubField[F] = Seq[F] 
type Field0[F] = (String, FieldLeaf[F]) 

type Field = Fix[Field0]