问题
I would like to generate functions for a class accepting 1 type parameter, which wraps a by name value.
class C[T](_t: => T) {
def t: T = _t
}
The functions I would like to generate are derived by the functions available on T
.
What I would like exactly, is to get all the functions available for T
, change their contract and implementation in a programmatic way, and make them available for C
.
By changing their contract, I mean changing their signature so they return
C[R]
, whereR
stands for the return type of the original function.By changing their implementation, I mean wrapping the result inside
C
before returning it.
eg.
def +(that: Int): Int =
this + that
would become available on C[Int]
as
def +(that: Int): C[Int] =
C(this.t + that)
This would be done in order to remove the boilerplate of having to wrap inside C
a computation in order to keep it non-evaluated.
eg.
val c1 = new C(1)
val c2: C[Int] = C(c1.t + 1)
c2.t == 2
would be able to be expressed also as
val c2: C[Int] = c1 + 1
c2.t == 2
How can I achieve this by using Scala 2 or dotty macros? Or, can this be achieved in another way?
回答1:
Try to add one more implicit conversion additionally to advised by @KrzysztofAtłasik in your previous question.
implicit def conversion[T](c: C[T]): T = c.t
implicit def conversion1[T](t: => T): C[T] = new C(t)
Or make class implicit
implicit class C[T](_t: => T) {
def t: T = _t
}
Regarding macros, since you want to add definitions you would need macro annotations rather than def macros. Dotty doesn't have macro annotations, it has only inline macros like Scala 2 def macros.
And macro annotations don't help either. When you define class C[T]
it's not known what T
is (this will be known only at call site), so it's not known what methods to add.
Dotty has implicit conversions too
given [T] as Conversion[T, C[T]] = new C(_)
given [T] as Conversion[C[T], T] = _.t
(currently it's given
, formerly it was implicit
, then implied
, then delegate
, currently in 0.17 given
, this can change again).
It seems Conversion[(=> T), C[T]]
is not allowed.
来源:https://stackoverflow.com/questions/56916413/generate-functions-based-on-type-parameter