Учитывая кодирование Shapeless копроизведений, отношения подмножеств такого типа не могут быть такими же, как подтип.Вместо этого есть класс типов, который обеспечивает доказательство того, что один сопутствующий продукт является вложенным в другой:
scala> import shapeless._
import shapeless._
scala> type ISB = Int :+: String :+: Boolean :+: CNil
defined type alias ISB
scala> type ISBSub = Int :+: String :+: CNil
defined type alias ISBSub
scala> shapeless.ops.coproduct.Basis[ISB, ISBSub]
res0: shapeless.ops.coproduct.Basis[Int :+: String :+: Boolean :+: shapeless.CNil,Int :+: String :+: shapeless.CNil]{type Rest = Boolean :+: shapeless.CNil} = shapeless.ops.coproduct$Basis$$anon$64@ddd69d2
Этот класс типа также позволяет преобразовывать значения любого типа копродукта в любом направлении:
import shapeless.ops.coproduct.Basis
def shrink[A <: Coproduct, B <: Coproduct](a: A)(implicit ev: Basis[A, B]): Option[B] =
ev(a).toOption
def enlarge[A <: Coproduct, B <: Coproduct](b: B)(implicit ev: Basis[A, B]): A =
ev.inverse(Right(b))
И затем:
scala> shrink[ISB, ISBSub](Coproduct[ISB](1))
res0: Option[ISBSub] = Some(Inl(1))
scala> enlarge[ISB, ISBSub](Coproduct[ISBSub](1))
res1: ISB = Inl(1)
В общем, стоит просмотреть содержимое пакетов shapeless.ops
, чтобы понять, какие виды операций поддерживаются для таких вещей, как копроизведения.