Копродукты в бесформенном виде не собираются
Я экспериментирую с 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
сам (источник).