为A&B类型创建给定的最简单方法是什么?



我有

trait Foo:
def foo: Int
trait Bar:
def bar: Int
given Foo with
def foo = 1
given Bar with
def bar = 1

我有一个函数foobar

type FooBar = Foo & Bar
def foobar(using FooBar) = ...

如果我已经给出了A和B ,那么为A & B类型创建给定的最简单方法是什么

您可以通过在given实例中嵌套using子句来获得Foo & Bar,但一旦您开始修改FooBar中的值,结果可能与您预期的不一样,因为FooBar也是FooBar,并且事情开始变得递归:

trait FooBar extends Foo with Bar
given (using f: Foo, b: Bar): FooBar with
def foo = f.foo + 1
def bar = b.bar + 2
def fooBar(using fb: Foo & Bar) = (fb.foo, fb.bar)
def foo(using f: Foo) = f.foo
def bar(using b: Bar) = b.bar
@main def main() =
println(foo) //2
println(bar) //3
println(fooBar) //(3, 5)

IMO您应该避免与typeclass的子类型关系,并在不扩展FooBar:的情况下定义FooBar

trait FooBar:
def foo: Int
def bar: Int
given (using f: Foo, b: Bar): FooBar with
def foo = f.foo + 1
def bar = b.bar + 2

所以,在大家的帮助下,我认为最简单的解决方案是

given (using f: Foo, b: Bar): Foo with Bar with 
export f.*
export b.*

诚然,我没有直接的Scala 3经验,但最简单的解决方案可以归结为:

given aAndB(using a: A, b: B): A & B with {
def foo: Int = a.foo
def bar: Int = b.bar
}

您有效地将A和B粘合在一起,并进行适当的调度。

可以实现一个自动调度(当没有冲突时(的宏。

AFAICT,这将相当于Scala2:

implicit def aAndB(implicit a: A, b: B) = new A with B {
def foo: Int = a.foo
def bar: Int = b.bar
}

相关内容

  • 没有找到相关文章

最新更新