如何避免在 Scala 中绑定类型重复
How to avoid duplication of type bound in Scala
我有一个带有约束类型参数的 class。
我试过 identity
但 return 类型不准确。
并且在方法identityTP
中,我需要再次指定约束
如何避免使用适用于此类型的方法重复此约束?
这是一个例子:
sealed trait Location
case object Single extends Location
case object Multi extends Location
final case class Log[L <: Location](l: L)
def identity(log: Log[_]): Log[_] = log
def identityTP[L<: Location](log: Log[L]): Log[L] = log
实际上这不是重复。 L
在
final case class Log[L <: Location](l: L)
和L
在
def identityTP[L <: Location](log: Log[L]): Log[L] = log
是两个完全不同的类型参数。如果您使用不同的标识符,这可能会更清楚
final case class Log[L <: Location](l: L)
def identityTP[L1 <: Location](log: Log[L1]): Log[L1] = log
一种类型参数的上限不会与其他类型参数的上限重复。
这也不是重复,因为实际上上限可能不同
sealed trait SubLocation extends Location
final case class Log[L <: Location](l: L)
def identityTP[L1 <: SubLocation](log: Log[L1]): Log[L1] = log
如果您不想创建第二个类型参数,您可以将 identityTP
嵌套到 Log
中(使其成为 Log
的方法)
final case class Log[L <: Location](l: L) {
def identityTP: Log[L] = this
}
有时将 L
设为类型成员而不是类型参数
会有所帮助
trait Log {
type L <: Location
val l: L
}
object Log {
// def apply[_L <: Location](_l: _L): Log { type L = _L} = new Log {
// override type L = _L
// override val l: L = _l
// }
def apply[_L <: Location](_l: _L): Log = new Log {
override type L = _L
override val l: L = _l
}
}
// def identityTP(log: Log): Log = log
def identityTP(log: Log): Log { type L = log.L } = log
请注意,虽然我们必须在 apply
中重复上界,但在 identityTP
中没有。
正常情况下,必要时重复上限没什么大不了的
class MyClass[A <: A1]
def foo[A <: A1](mc: MyClass[A]) = ???
def bar[A <: A1](mc: MyClass[A]) = ???
当这变得麻烦时
class MyClass[A <: A1, B <: B1, C <: C1]
def foo[A <: A1, B <: B1, C <: C1](mc: MyClass[A, B, C]) = ???
def bar[A <: A1, B <: B1, C <: C1](mc: MyClass[A, B, C]) = ???
你应该重新设计你的抽象。例如
trait Tuple {
type A <: A1
type B <: B1
type C <: C1
}
class MyClass[T <: Tuple]
def foo[T <: Tuple](mc: MyClass[T]) = {
//T#A, T#B, T#C instead of A, B, C
???
}
或
class MyClass[T <: Tuple](val t: T)
//class MyClass(val t: Tuple)
def foo[T <: Tuple](mc: MyClass[T]) = {
//def foo(mc: MyClass) = {
import mc.t
//t.A, t.B, t.C instead of A, B, C
???
}
有时您也可以尝试用类型约束替换类型边界
final case class Log[L](l: L)(implicit ev: L <:< Location)
def identityTP[L](log: Log[L])(implicit ev: L <:< Location): Log[L] = log
虽然这不会消除重复,但也有一些方法可以防止隐式参数之间的重复(类型 类)。参见
我有一个带有约束类型参数的 class。
我试过 identity
但 return 类型不准确。
并且在方法identityTP
中,我需要再次指定约束
如何避免使用适用于此类型的方法重复此约束?
这是一个例子:
sealed trait Location
case object Single extends Location
case object Multi extends Location
final case class Log[L <: Location](l: L)
def identity(log: Log[_]): Log[_] = log
def identityTP[L<: Location](log: Log[L]): Log[L] = log
实际上这不是重复。 L
在
final case class Log[L <: Location](l: L)
和L
在
def identityTP[L <: Location](log: Log[L]): Log[L] = log
是两个完全不同的类型参数。如果您使用不同的标识符,这可能会更清楚
final case class Log[L <: Location](l: L)
def identityTP[L1 <: Location](log: Log[L1]): Log[L1] = log
一种类型参数的上限不会与其他类型参数的上限重复。
这也不是重复,因为实际上上限可能不同
sealed trait SubLocation extends Location
final case class Log[L <: Location](l: L)
def identityTP[L1 <: SubLocation](log: Log[L1]): Log[L1] = log
如果您不想创建第二个类型参数,您可以将 identityTP
嵌套到 Log
中(使其成为 Log
的方法)
final case class Log[L <: Location](l: L) {
def identityTP: Log[L] = this
}
有时将 L
设为类型成员而不是类型参数
trait Log {
type L <: Location
val l: L
}
object Log {
// def apply[_L <: Location](_l: _L): Log { type L = _L} = new Log {
// override type L = _L
// override val l: L = _l
// }
def apply[_L <: Location](_l: _L): Log = new Log {
override type L = _L
override val l: L = _l
}
}
// def identityTP(log: Log): Log = log
def identityTP(log: Log): Log { type L = log.L } = log
请注意,虽然我们必须在 apply
中重复上界,但在 identityTP
中没有。
正常情况下,必要时重复上限没什么大不了的
class MyClass[A <: A1]
def foo[A <: A1](mc: MyClass[A]) = ???
def bar[A <: A1](mc: MyClass[A]) = ???
当这变得麻烦时
class MyClass[A <: A1, B <: B1, C <: C1]
def foo[A <: A1, B <: B1, C <: C1](mc: MyClass[A, B, C]) = ???
def bar[A <: A1, B <: B1, C <: C1](mc: MyClass[A, B, C]) = ???
你应该重新设计你的抽象。例如
trait Tuple {
type A <: A1
type B <: B1
type C <: C1
}
class MyClass[T <: Tuple]
def foo[T <: Tuple](mc: MyClass[T]) = {
//T#A, T#B, T#C instead of A, B, C
???
}
或
class MyClass[T <: Tuple](val t: T)
//class MyClass(val t: Tuple)
def foo[T <: Tuple](mc: MyClass[T]) = {
//def foo(mc: MyClass) = {
import mc.t
//t.A, t.B, t.C instead of A, B, C
???
}
有时您也可以尝试用类型约束替换类型边界
final case class Log[L](l: L)(implicit ev: L <:< Location)
def identityTP[L](log: Log[L])(implicit ev: L <:< Location): Log[L] = log
虽然这不会消除重复,但也有一些方法可以防止隐式参数之间的重复(类型 类)。参见