Копродукты в бесформенном виде не собираются

Я экспериментирую с shapeless а теперь пытаюсь понять Genericдля копродуктов. Вот что я пробовал:

object ShapelessExperiments {
    final case class Test1()
    final case class Test2()
    final case class Test3()

    type Test = Test1 :+: Test2 :+: Test3 :+: CNil

    val t1: Test = Inr(Inl(Test2()))  //fine
    val t2: Test = Generic[Test].to(Test2())  //compile error
}

Я ожидал val t2 быть точно таким же, как val t1, но, к сожалению, он даже не компилируется:

Error:(13, 25) could not find implicit value for parameter gen: shapeless.Generic[com.test.ShapelessExperiments.Test]
  val t2: Test = Generic[Test].to(Test2())

Error:(13, 25) not enough arguments for method apply: (implicit gen: shapeless.Generic[com.test.ShapelessExperiments.Test])shapeless.Generic.Aux[com.test.ShapelessExperiments.Test,gen.Repr] in object Generic.
Unspecified value parameter gen.
  val t2: Test = Generic[Test].to(Test2())

Эта ошибка не совсем понятна и мне не помогает. Не могли бы вы объяснить, что пошло не так в последнем случае?

1 ответ

Решение

Я думаю ты ищешь Inject:

import shapeless._
import shapeless.ops.coproduct.Inject // for converter object
import shapeless.syntax.inject._ // for nice syntax

object ShapelessExperiments extends App {
    final case class Test1()
    final case class Test2()
    final case class Test3()

    type Test = Test1 :+: Test2 :+: Test3 :+: CNil

    val t1: Test = Inr(Inl(Test2()))  //fine
    val t2: Test = Inject[Test, Test2].apply(Test2())
    val t3: Test = Test2().inject[Test]
    println(t1 == t2) // true
    println(t1 == t3) // true 
}

Generic[A] цель другая: он говорит, что A изоморфен (может быть преобразован в и из без потери данных) некоторому типу B, где B обычно HList (если A это класс случая) или Coproduct (если A запечатанная черта).

Эти экземпляры недоступны, когда A является HList или Coproductсам (источник).

Другие вопросы по тегам