1

で再帰的な文法について説明します。は、私は型の別名で、この再帰的な文法を記述することができますどのように型の別名

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

現状では、Scalaのコンパイラ(2.12.1)が私を与える:

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

PS文脈はfastparseで再帰文法を解析しています。


編集(以下OlivierBlanvillainの答え@に応答して)

答えは本当に美しさのものだったと私が探していたまさに、私は将来のためにそれを覚えているだろうと。しかし、他の理由のために、この特定のケースでは、私が代わりにこれらの定義を行っていた

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 

も参照してください: Instantiate types from recursive type grammar

+0

'CNil'と'どのようなものですか:+: '? – Rumid

+0

また、どのような構造になっているのか説明できるかもしれません。おそらく設計上の誤りです。 'Type Subfield'を取り除き、' Seq [Field] 'を使って問題を解決する必要がありますが、例えばクラスを追加するなどの解決策があるかもしれません。 – Rumid

+1

申し訳ありませんが、輸入品が含まれているはずです。私はそれらを簡潔にするために除外した。それはシェイプレスです。 – eirirlar

答えて

2

固定小数点型を使用します。たとえば:

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

は、あなたが書くことができます:

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] 
関連する問題