Генерация функций на основе параметра типа - PullRequest
2 голосов
/ 06 июля 2019

Я хотел бы сгенерировать функции для класса, принимающего параметр типа 1, который заключает в себе значение по имени.

class C[T](_t: => T) {
    def t: T = _t
}

Функции, которые я хотел бы генерировать, получены функциями, доступными в T.

Что бы я хотел, это получить все функции, доступные для T, изменить их контракт и реализацию программным способом и сделать ихдоступно для C.

  • Под изменением их контракта я подразумеваю изменение их подписи, чтобы они возвращали C[R], где R обозначает тип возврата исходной функции.

  • Под изменением их реализации я подразумеваю оборачивание результата в C перед его возвратом.

например.

def +(that: Int): Int =
    this + that

станет доступным для C[Int] как

def +(that: Int): C[Int] =
    C(this.t + that)

Это будет сделано для того, чтобы убрать шаблон необходимости переноса внутри C вычисления, чтобы не оценивать его.

напр.

val c1 = new C(1)

val c2: C[Int] = C(c1.t + 1)
c2.t == 2

woВы также можете быть выражены также как

val c2: C[Int] = c1 + 1
c2.t == 2

Как я могу достичь этого с помощью макросов Scala 2 или dotty?Или это может быть достигнуто по-другому?

1 Ответ

3 голосов
/ 06 июля 2019

Попробуйте добавить еще одно неявное преобразование в дополнение к совету @ KrzysztofAtłasik в вашем предыдущем вопросе .

implicit def conversion[T](c: C[T]): T = c.t
implicit def conversion1[T](t: => T): C[T] = new C(t)

Или сделайте класс неявным

implicit class C[T](_t: => T) {
  def t: T = _t
}

Относительномакросы, поскольку вы хотите добавить определения, вам понадобится аннотаций макросов вместо def макросов .У Дотти нет макросовых аннотаций, у него есть только встроенных макросов , таких как макросы определения Scala 2.

И макросовые аннотации тоже не помогают.Когда вы определяете класс C[T], неизвестно, что такое T (это будет известно только на сайте вызова), поэтому неизвестно, какие методы добавить.

У Дотти тоже есть неявные преобразования

given [T] as Conversion[T, C[T]] = new C(_)
given [T] as Conversion[C[T], T] = _.t

(в настоящее время это given, ранее это было implicit, затем implied, затем delegate, в настоящее время в 0,17 given, это может измениться снова).

КажетсяConversion[(=> T), C[T]] не допускается.

...