Scala 3扩展重载不同泛型类型



我正在从Scala 2.13迁移到Scala 3,我正在尝试重写小的实用程序函数。在2.13中,可以编写一个更泛型的隐式和另一个更具体的隐式,但在Scala 3中似乎不再可能了。

type Outcome[+E <: Fail, A] = Either[E, A]
extension[A] (list: List[Outcome[ValidationFail, A]]) {
def outcomeListAll: Outcome[ValidationFail, List[A]] = {
val (left, right) = list.partitionOutcome
if (left.isEmpty) {
Right(right)
} else {
Left(left.reduce(_ + _))
}
}
}
extension[F <: Fail, A] (list: List[Outcome[F, A]])
@deprecated
def outcomeListAll: Outcome[Fail, List[A]] = {
val (left, right) = partitionOutcome
if (left.isEmpty) {
Right(right)
} else {
Left(Fail.generic(left.map(_.getMessage).mkString(", "), left.head))
}
}
def partitionOutcome: (List[F], List[A]) = {
val left: List[F] = list.collect {
case Left(l) => l
}
val right: List[A] = list.collect {
case Right(r) => r
}
(left, right)
}

当我尝试编译上面的代码片段时,我得到双定义错误。至少根据这篇文章应该解决具有不同签名的方法。像这样:

<extension> def < (x: String)(y: String): Boolean = ...
<extension> def +: (xs: Seq[Elem])(x: Elem): Seq[Elem] = ...
<extension> infix def min(x: Number)(y: Number): Number = ...

我知道我可以简单地使用模式匹配,但是我不能像你那样用方法重载扩展,这似乎很奇怪。

编译错误:

[error] -- [E120] Naming Error: /home/...testing/Main.scala:19:8 
[error] 19 |    def outcomeListAll: Outcome[Fail, List[A]] = {
[error]    |        ^
[error]    |Double definition:
[error]    |def outcomeListAll(list: scala.collection.immutable.List): scala.util.Either in object Main at line 7 and
[error]    |def outcomeListAll(list: scala.collection.immutable.List): scala.util.Either in object Main at line 19
[error]    |have the same type after erasure.
[error]    |
[error]    |Consider adding a @targetName annotation to one of the conflicting definitions
[error]    |for disambiguation.

用户指出,可以使用注释@targetName("...")

来解决这个问题。
import scala.annotation.targetName
type Outcome[+E <: Fail, A] = Either[E, A]
extension[A] (list: List[Outcome[ValidationFail, A]]) {
@targetName("outcomeListAllForValidationFail")
def outcomeListAll: Outcome[ValidationFail, List[A]] = {
val (left, right) = list.partitionOutcome
if (left.isEmpty) {
Right(right)
} else {
Left(left.reduce(_ + _))
}
}
}
extension[F <: Fail, A] (list: List[Outcome[F, A]])
def outcomeListAll: Outcome[Fail, List[A]] = {
val (left, right) = partitionOutcome
if (left.isEmpty) {
Right(right)
} else {
Left(Fail.generic(left.map(_.getMessage).mkString(", "), left.head))
}
}
def partitionOutcome: (List[F], List[A]) = {
val left: List[F] = list.collect {
case Left(l) => l
}
val right: List[A] = list.collect {
case Right(r) => r
}
(left, right)
}

相关内容

  • 没有找到相关文章

最新更新