Можно ли обернуть типы членов другим типом в Scala 3, подобным отображаемым типам машинописного текста?

В машинописном тексте это выглядит так

type Option<T> = {some: T} | 'none'
type Optional<T> = {
  [P in keyof T]: Option<T[P]>
};
type Foo = {x: string, y: number}
type OptionalFoo = Optional<Foo>
const foo: OptionalFoo = {x: 'none', y : {some: 123}}
case class Foo(x: String, y: Int)

Я бы хотел

type OptionalFoo = Optional[Foo] == case class OptionalFoo(x: Option[String], y: Option[Int])

Возможно ли добиться чего-то подобного в Scala 3?


person ais    schedule 20.01.2021    source источник
comment
Насколько я знаю, не тогда, когда у вас есть переменное количество полей.   -  person user    schedule 20.01.2021
comment
Здесь похожий вопрос, но я сомневаюсь, что вы там что-нибудь найдете. Возможно, вам просто придется написать плагин компилятора самостоятельно или, к сожалению, найти обходной путь.   -  person user    schedule 20.01.2021


Ответы (1)


Если вас не интересуют имена каждого поля, возможно, вы могли бы сделать это:

type Foo = (String, Int)
type Optional[T <: Tuple] = Tuple.Map[T, Option]
type OptionalFoo = Optional[Foo]

val optionalFoo: OptionalFoo = (Some("foobar"), None)
optionalFoo match {
  case (x, y) => println(s"x is $x, y is $y")
}

Scastie

Это могло быть возможно в Scala 2, который поддерживал макросы аннотаций. Возможно, здесь вам может помочь вывод классов типов. Shapeless также имеет много полезных механизмов, если вы не заботитесь о фактическом создании совершенно нового класса case.

person user    schedule 20.01.2021
comment
Спасибо. Можно ли это реализовать для type Foo = (("x", String),("y", Int))? Можно ли преобразовать класс case в такие кортежи в Scala 3? - person ais; 21.01.2021
comment
@ais Преобразовать класс case в кортеж? Бесформенный, вероятно, может это сделать. Но я подумал, что вы хотите сделать case class из кортежем. Я неправильно истолковал ваш вопрос? - person user; 21.01.2021
comment
Я подумал, что, возможно, такой сценарий возможен case class Foo(x: String, x: Int) преобразовать в кортеж type Foo = (("x", String),("y", Int)) и преобразовать кортеж с помощью Optional[Foo] == (("x", Option[String]),("y", Option[Int])) и использовать такой кортеж как некую альтернативу класса case. - person ais; 21.01.2021
comment
@ais Вы можете напрямую превратить кортежную версию Foo в кортеж кортежей. Дай мне минуту - person user; 21.01.2021