2017-02-02 1 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

굉장! 고마워, 마일즈. 이것에 대한 측면 질문. 이러한 val의 정의는 주어진 클래스의 메모리 공간을 두 배로 늘립니까? – expert

+0

여기에는 val 하나만 있습니다. 비 - case 클래스의 생성자 인수는 명시 적으로 표시되지 않는 한 val을 생성하지 않습니다. –

+0

알겠습니다. 나는'def getDegrees'가 그것을 반환 할 수 있다면 여전히 어딘가에 저장되어야한다고 생각했습니다. – expert

관련 문제