Shapless субпродукт подтип - PullRequest
4 голосов
/ 21 сентября 2019

Я пытаюсь подражать хотя бы некоторым аспектам типов объединения в Scala 2.13.

На данный момент лучший подход, который отвечает моим потребностям, это coproduct из бесформенного.Единственная проблема заключается в том, что подтип не работает, как я ожидал.Вот пример:

import shapeless._

type ISB = Int :+: String :+: Boolean :+: CNil

type ISBSub = Int :+: String :+: CNil

implicitly[ISBSub <:< ISB] // error here

Я пытаюсь создать метод с параметром типа ISB и хочу также def принять ISBSub.

def test(t: ISB) = ???

test(Coproduct[ISBSub](2)) // not working

Есть ли способ достичь чего-то подобного с coproduct?

1 Ответ

6 голосов
/ 21 сентября 2019

Учитывая кодирование 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, чтобы понять, какие виды операций поддерживаются для таких вещей, как копроизведения.

...