Scala,协变类型定义
Scala, covariant type definition
我有一组 类 继承自 Step[I, O]
,其中 I
是输入,O
是输出。我想定义一个不关心 I
.
的更具体的子类
这是我的定义:
trait Step[I, O] {
def apply(c:Context, i:I):Either[Error, O]
}
// H : Action handler
// A : Action handled by H
// R : Result of successful A
class Legacy[H, A <: Action[H], R](action: A with Result[R], handler: H) extends Step[Any, R] {
override def apply(c:Context, a: Any): Either[Error, R] = {
handler.run(action)
}
}
但是那些 步骤 是通过 DSL 链接起来的,DSL 使用一个步骤的输出 O
作为下一个步骤的输入 I
。
// DSL excerpt
class AndThenBuilder[I] {
def andThen[O](producer: (Context, I) => Step[I, O]) = ???
}
//...
val intToString:Step[Int, String] = //new SubType of Step
val legacy:Step[Any, String] = // new Legacy( action with Result[String])
//...
execute(intToString) // return AndThenBuilder[String]
.andThen((_:Context, s:String)=>legacy)
最后一行,不编译,因为 DSL 验证类型:
Required : (Context, String) => Step[String, NotInferedO]
Found : (Context, String) => Step[Any, String]
我想将 Step[I, O]
更改为 Step[I_Or_Subtypes, O]
可以解决我的问题。但是我找不到在 Step
或 Legacy
中定义它的语法,每次尝试都给我一个更神秘的信息。
有人可以帮助我更改我的代码,以便 Step[Any, String]
被接受为 Step[String, String]
。 (我可以把Any
改成其他类型)?
谢谢
so that Step[Any, String]
will be accepted as a Step[String, String]
这需要第一个参数是 contra-variant,而不是标题中的协变。语法是
trait Step[-I, O] { ... }
碰巧,I
可以是逆变的,但不是协变的,因为它被用作方法参数类型。虽然O
可以是协变的,但不能是逆变的。
我有一组 类 继承自 Step[I, O]
,其中 I
是输入,O
是输出。我想定义一个不关心 I
.
这是我的定义:
trait Step[I, O] {
def apply(c:Context, i:I):Either[Error, O]
}
// H : Action handler
// A : Action handled by H
// R : Result of successful A
class Legacy[H, A <: Action[H], R](action: A with Result[R], handler: H) extends Step[Any, R] {
override def apply(c:Context, a: Any): Either[Error, R] = {
handler.run(action)
}
}
但是那些 步骤 是通过 DSL 链接起来的,DSL 使用一个步骤的输出 O
作为下一个步骤的输入 I
。
// DSL excerpt
class AndThenBuilder[I] {
def andThen[O](producer: (Context, I) => Step[I, O]) = ???
}
//...
val intToString:Step[Int, String] = //new SubType of Step
val legacy:Step[Any, String] = // new Legacy( action with Result[String])
//...
execute(intToString) // return AndThenBuilder[String]
.andThen((_:Context, s:String)=>legacy)
最后一行,不编译,因为 DSL 验证类型:
Required : (Context, String) => Step[String, NotInferedO]
Found : (Context, String) => Step[Any, String]
我想将 Step[I, O]
更改为 Step[I_Or_Subtypes, O]
可以解决我的问题。但是我找不到在 Step
或 Legacy
中定义它的语法,每次尝试都给我一个更神秘的信息。
有人可以帮助我更改我的代码,以便 Step[Any, String]
被接受为 Step[String, String]
。 (我可以把Any
改成其他类型)?
谢谢
so that
Step[Any, String]
will be accepted as aStep[String, String]
这需要第一个参数是 contra-variant,而不是标题中的协变。语法是
trait Step[-I, O] { ... }
碰巧,I
可以是逆变的,但不是协变的,因为它被用作方法参数类型。虽然O
可以是协变的,但不能是逆变的。