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?