1

我在一个重度类型系统上,其中一些泛型方法声明为def execute]C <: A#C](cmd: C):EitherT[Future, Fail, Seq[A#E]]A 类中的泛型类型在哪里。

这很好用。然而,在我的测试中,当我模拟这些调用时,我必须明确键入超类型,Fail或者A#E我的代码无法编译。

// Event is the base type of Receiver#E
val event:Event = SubOfEvent()
handler.execute(any[SubOfCommand]) returns Seq(event).asRightT[Future, Fail]

val fail:Fail = SubOfFail()
handler.execute(any[SubOfCommand]) returns fail.asLeftT[Future, Seq[Receiver#E]]

如果我内联声明eventfail我有一个类型不匹配

  found   : cats.data.EitherT[scala.concurrent.Future,SubOfFail,scala.collection.immutable.Seq[SubOfEvent]]
  required: cats.data.EitherT[scala.concurrent.Future,Fail,scala.collection.immutable.Seq[Receiver#E]]
     (which expands to)  cats.data.EitherT[scala.concurrent.Future,Fail,scala.collection.immutable.Seq[Event]]
 Note: SubOfFail <: Fail, but class EitherT is invariant in type A.
 You may wish to define A as +A instead. (SLS 4.5)
     handler.execute(any[SubOfCommand]) returns SubOfFail().asLeftT[Future,
                                                                   ^

我理解关于EitherT类型不变的信息A。但我期待它能够翻译EitherT[F, SubOfA, B]EitherT[F, SubOfA.asInstanceOf[A], B].

有人可以帮我揭示我推理中的缺陷吗?

谢谢

4

1 回答 1

1

但我期待它能够翻译EitherT[F, SubOfA, B]EitherT[F, SubOfA.asInstanceOf[A], B].

不变意味着不可能以这种方式“翻译”: anEitherT[F, SubOfA, B]根本不是EitherT[F, A, B].

现在,一个单独的问题是尽管 for 的类型是预期的,但为什么fail没有推断出Fail整个fail.asLeftT[Future, Seq[Receiver#E]]. 答案是 Scala 类型推断不能那样工作。键入时expression.method(...),它会expression先键入,并且不能使用 . 的预期返回类型method

您仍然可以内联编写它们,但您需要类型归属:

(SubOfFail(): Fail).asLeftT[Future, Seq[Receiver#E]]

在 的情况下Seq,显式类型参数也将起作用:

Seq[Event](SubOfEvent()).asRightT[Future, Fail]
于 2019-10-07T09:03:56.657 回答