gpt4 book ai didi

scala - 如何比较 Scala 特征中的有序抽象类型?

转载 作者:行者123 更新时间:2023-12-04 17:55:50 25 4
gpt4 key购买 nike

给出方法下面的代码 foo应该按运算符比较给定参数 barlowerBoundupperBound所有都是相同的抽象类型 Bar .

trait Foo {
type Bar <: Ordered[Bar]
val lowerBound: Bar
val upperBound: Bar
def foo(bar: Bar) = bar >= lowerBound && bar <= upperBound
}

这样的特质 Foo可以定义。问题始于下面的具体类 FooImpl .
class FooImpl extends Foo {
type Bar = Int
val lowerBound = 0
val upperBound = 5
}

我明白 scala.Int没有实现什么 scala.runtime.RichInt确实有效 scala.math.Ordered[Int] .定义类型 BarRichInt相反,两者都不起作用,因为它不符合 scala.math.Ordered[RichInt] .我第三次尝试定义类型 BarOrdered[Ord]哪里 Ord声明为 type Ord并在 FooImpl 中定义它如 Int也没有用。

一个可能接近的解决方案会是什么样子?

最佳答案

可能有更优雅的解决方案,但您可以通过将类型限制移动到方法而不是类型声明来实现这一点:

trait Foo {
type Bar
val lowerBound: Bar
val upperBound: Bar
def foo(bar: Bar)(implicit ev: Bar => Ordered[Bar]) = {
bar >= lowerBound && bar <= upperBound
}
}

那么你的 FooImpl像你一样工作:
class FooImpl extends Foo {
type Bar = Int
val lowerBound = 0
val upperBound = 5
}

来自 REPL:
scala> new FooImpl()
res0: FooImpl = FooImpl@2dbbec72

scala> res0.foo(3)
res1: Boolean = true

scala> res0.foo(7)
res2: Boolean = false

这里的缺点是可以使用无序类型扩展特征(尽管在这种情况下不能调用 foo):
class A // not Ordered

class BrokenFoo extends Foo {
type Bar = A
val lowerBound = new A
val upperBound = new A
} // compiles

new BrokenFoo().foo(new A) // doesn't compile

或者,您可以将需求保留在类级别(因此阻止任何人创建 BrokenFoo ),如下所示,但 FooImpl必须稍微改变:
trait Foo {
type Bar
implicit val baz: Bar => Ordered[Bar]
val lowerBound: Bar
val upperBound: Bar
def foo(bar: Bar) = { bar >= lowerBound && bar <= upperBound }
}

class FooImpl extends Foo {
type Bar = Int
val baz = implicitly[Bar => Ordered[Bar]]
val lowerBound = 0
val upperBound = 5
}

这个问题感觉就像 view or context bounds应该适用,但不幸的是,您似乎无法在 type 中使用它们。声明或在特征的泛型类型参数中。

关于scala - 如何比较 Scala 特征中的有序抽象类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9254027/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com