我正在從 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.
uj5u.com熱心網友回復:
正如用戶所指出的,問題可以通過使用注釋來解決@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)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/318743.html