[英]Scala, override method on generic type
I am trying to build a DSL , one of the method on this DSL is parameterless and use a bounded generic type.我正在尝试构建DSL ,此 DSL 上的方法之一是无参数的,并使用有界泛型类型。 Today I have to add a "feature" that will ideally use the same method name.
今天我必须添加一个“功能”,理想情况下将使用相同的方法名称。 However, because the only parameter is the generic one, I cannot override it with the usual way.
但是,因为唯一的参数是通用参数,所以我不能用通常的方式覆盖它。
Is there a trick to allow the use of the same method for different generic types ?是否有允许对不同泛型类型使用相同方法的技巧?
My method looks like:我的方法看起来像:
def ask[H <: Handler] = {
new CommandBuilder[H]
}
class CommandBuilder[H <: Handler] {
def toExecute[C <: H#C](command: C) = {
//...
}
}
And I would like to add:我想补充一点:
def ask[S <: State] = {
new QueryBuilder[S]
}
class QueryBuilder[S <: State] {
def toExecute[Q <: S#Q](query: Q) = {
//...
}
}
I was thinking to pattern match a ClassTag
on the type but I need strong type safety:我想在类型上模式匹配
ClassTag
但我需要强类型安全:
Query
on a Handler
, is not allowed.Query
Handler
。 ask[State] must return QueryBuilder Command
and Query
are the only supported types. Command
和Query
是唯一支持的类型。 The generic type of ask
can only be a Handler
or a State
. ask
的通用类型只能是Handler
或State
。Maybe you could refactor your code to something like this?也许你可以将你的代码重构为这样的东西?
sealed trait FooBar
sealed trait Foo extends FooBar {
def process(i: Int): Int
}
object Foo {
implicit final case object FooImpl extends Foo {
override def process(i: Int): Int = i + 1
}
}
sealed trait Bar extends FooBar {
def process(s: String): String
}
object Bar {
implicit final case object BarImpl extends Bar {
override def process(s: String): String = s.toUpperCase
}
}
object Test {
trait FooBarPartiallyApplied[FB <: FooBar] {
type Out
def out: Out
}
object FooBarPartiallyApplied {
type Aux[FB <: FooBar, _Out] = FooBarPartiallyApplied[FB] { type Out = _Out }
implicit final def FooPartiallyAppliedBuilder[F <: Foo]: Aux[F, FooPartiallyApplied[F]] =
new FooBarPartiallyApplied[F] {
override final type Out = FooPartiallyApplied[F]
override final val out: FooPartiallyApplied[F] =
new FooPartiallyApplied[F](dummy = true)
}
implicit final def BarPartiallyAppliedBuilder[B <: Bar]: Aux[B, BarPartiallyApplied[B]] =
new FooBarPartiallyApplied[B] {
override final type Out = BarPartiallyApplied[B]
override final val out: BarPartiallyApplied[B] =
new BarPartiallyApplied[B](dummy = true)
}
final class FooPartiallyApplied[F <: Foo](private val dummy: Boolean) extends AnyVal {
def toExecute(i: Int)(implicit foo: F): Int = foo.process(i)
}
final class BarPartiallyApplied[B <: Bar](private val dummy: Boolean) extends AnyVal {
def toExecute(s: String)(implicit bar: B): String = bar.process(s)
}
}
def ask[FB <: FooBar](implicit pa: FooBarPartiallyApplied[FB]): pa.Out =
pa.out
}
It works as expected:它按预期工作:
Test.ask[Foo.FooImpl.type].toExecute(10)
// res: Int = 11
Test.ask[Foo.FooImpl.type].toExecute("blah")
// Type error.
Test.ask[Bar.BarImpl.type].toExecute(10)
// Type error.
Test.ask[Bar.BarImpl.type].toExecute("blah")
// res: String = "BLAH"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.