2

我想为接受 1 类型参数的类生成函数,该参数包含按名称值。

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

我想生成的函数是由T.

我真正想要的是获得所有可用的功能T,以编程方式更改它们的合同实现,并使它们可用于C.

  • 通过更改他们的合同,我的意思是更改他们的签名以便他们 return 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

也可以表示为

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

如何通过使用 Scala 2 或 dotty 宏来实现这一点?或者,这可以通过其他方式实现吗?

4

1 回答 1

3

尝试在您上一个问题中的@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 macros。Dotty 没有宏注释,它只有像 Scala 2 def 宏这样的内联宏。

宏注释也无济于事。当您定义类C[T]时,不知道是什么T(这仅在调用站点知道),因此不知道要添加哪些方法。

Dotty 也有隐式转换

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]]是不允许的。

于 2019-07-06T18:00:34.933 回答