简体   繁体   English

Scala,协变类型定义

[英]Scala, covariant type definition

I have a set of classes inheriting from Step[I, O] where I is the input and O the output.我有一组从Step[I, O]继承的类Step[I, O]其中I是输入, O是输出。 I would like to define a more specific subclass that don't care about the I .我想定义一个不关心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 链接起来,该 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)

The last line, does not compile because the DSL verify the type:最后一行,不编译,因为 DSL 验证类型:

Required : (Context, String) => Step[String, NotInferedO]必需 : (Context, String) => Step[String, NotInferedO]

Found : (Context, String) => Step[Any, String]找到 : (Context, String) => Step[Any, String]

I guess that changing Step[I, O] to Step[I_Or_Subtypes, O] would solve my issue.我想将Step[I, O]更改为Step[I_Or_Subtypes, O]可以解决我的问题。 But I cannot find the syntax to define it in Step or Legacy , each attempt give me a more cryptic message.但是我找不到在StepLegacy定义它的语法,每次尝试都会给我一个更神秘的信息。

Can someone help me to change my code so that Step[Any, String] will be accepted as a Step[String, String] .有人可以帮我更改我的代码,以便Step[Any, String]将被接受为Step[String, String] (I can change Any by other types) ? (我可以通过其他类型更改Any )?

Thanks谢谢

so that Step[Any, String] will be accepted as a Step[String, String]这样Step[Any, String]将被接受为Step[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.碰巧的是, I可以是逆变的,但不是协变的,因为它被用作方法参数类型。 While O can be covariant, but can't be contravariant.虽然O可以是协变的,但不能是逆变的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM