2017-02-02 11 views
2

私は既存のプロジェクトでディスクリミネータを使用しようとしています。scodec.Codecが存在しないため、暗黙の値です。値のないフィールドを持つクラスのため暗黙的です

これを考慮するscodec example。私は

sealed class TurnLeft(degrees: Int) extends Command { 
    def getDegrees: Int = degrees 
} 
implicit val leftCodec: Codec[TurnLeft] = uint8or16.xmap[TurnLeft](v => new TurnLeft(v), _.getDegrees) 

TurnLeft、そのコーデックを変更した場合、私はdegreesフィールド値フィールドを作る場合、私は

Error:(x, x) could not find Lazy implicit value of type scodec.Codec[Command] 
    val codec: Codec[Either[UnrecognizedCommand, Command]] = discriminatorFallback(unrecognizedCodec, Codec[Command]) 

それはすべての作品を取得します。私は、それは形がつかないとやっかいなことだと思う。それを機能させるために私は何をすべきですか?

問題を示すサンプルプロジェクトはhereです。

答えて

1

シェイプレスのGenericは、 "case-class-like"タイプに対して定義されています。最初の近似では、ケースクラスのような型は、その値をそのコンストラクタのパラメータに分解することができ、その値を等しい値を再構築するために使用することができます。単一のコンストラクタパラメータリストと

case class Foo ... 
val foo = Foo(...) 
val fooGen = Generic[Foo] 
assert(fooGen.from(fooGen.to(foo)) == foo) 

ケースクラスは、パブリック(怠け者)自分のコンストラクタパラメータのヴァルス、または一致apply/unapplyでコンパニオンを持っていないクラスのに対し、ない、この基準を満たします。

Genericの実装はかなり許可されており、アクセス可能なコンストラクタ引数と同等である(型と順序によって)コンストラクタパラメータに対応する(怠惰な)valメンバーを扱うことになるので、このような何か、この場合getDegrees

sealed class TurnLeft(degrees: Int) extends Command { 
    val getDegrees: Int = degrees 
} 

scala> Generic[TurnLeft] 
res0: shapeless.Generic[TurnLeft]{type Repr = Int :: HNil } = ... 

は、単一Intコンストラクタパラメータのアクセサとして扱われていること。

+0

恐ろしく!ありがとう、マイルス。これについての側面の質問。これらの値の定義は、指定されたクラスの2倍のメモリフットプリントですか? – expert

+0

ここにvalが1つしかありません。非大文字クラスのコンストラクタ引数は明示的にそのようにマークされない限りvalを生成しません。 –

+0

私は参照してください。 'def getDegrees'がそれを返すことができるならば、まだどこかに格納しなければならないと思いました。 – expert

関連する問題