I have a set of classes inheriting from Step[I, O]
where I
is the input and O
the output. I would like to define a more specific subclass that don't care about the I
.
Here a my definitions :
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)
}
}
But those steps are chained trough a DSL that use the output O
of a step as the input I
of the next one.
// 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)
The last line, does not compile because the DSL verify the type:
Required : (Context, String) => Step[String, NotInferedO]
Found : (Context, String) => Step[Any, String]
I guess that changing Step[I, O]
to Step[I_Or_Subtypes, O]
would solve my issue. But I cannot find the syntax to define it in Step
or Legacy
, each attempt give me a more cryptic message.
Can someone help me to change my code so that Step[Any, String]
will be accepted as a Step[String, String]
. (I can change Any
by other types) ?
Thanks
so that
Step[Any, String]
will be accepted as aStep[String, String]
This needs the first parameter to be contra -variant, not covariant as in your title. And the syntax is
trait Step[-I, O] { ... }
And as it happens, I
can be contravariant, but not covariant, because it's used as a method argument type. While O
can be covariant, but can't be contravariant.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.