在此示例中,为什么 Scala 3 无法减少对 Either 的内联匹配?
Why does Scala 3 fail to reduce an inline match over Either in this example?
在试验 Scala 3 的元编程功能时,我发现了这个内联匹配问题,我无法解释清楚。
给定一个透明内联方法 eitherTest
,它采用内联 Either[String, Int]
然后 returns String
或 Int
直接使用内联匹配表达式,如果将 eitherTest
的输入显式键入 Left
或 Right
,则一切正常。但是,如果输入被显式键入 Either
的超类型,编译器似乎无法减少匹配表达式。更奇怪的是 eitherTest
的参数本身被键入为 Either
.
这是编译器错误吗?这是预期的行为吗?我很难理解为什么编译器无法解决这个问题。
斯卡斯蒂 link: https://scastie.scala-lang.org/CThqajauRVeJvxvW0uYy4w
代码:
@main def hello: Unit =
workingTest
failingTest
def workingTest: Unit =
val l: Left[String, Int] = Left("hello")
val r: Right[String, Int] = Right(22)
val tl: String = eitherTest(l)
val tr: Int = eitherTest(r)
println(s"$tl :: $tr")
def failingTest: Unit =
val l: Either[String, Int] = Left("hello")
val r: Either[String, Int] = Right(22)
val tl: String = eitherTest(l)
val tr: Int = eitherTest(r)
println(s"$tl :: $tr")
transparent inline def eitherTest(inline v: Either[String, Int]): Any =
inline v match
case Right(a) => a
case Left(b) => b
错误:
cannot reduce inline match with
scrutinee: l : (l : Either[String, Int])
patterns : case Right.unapply[String, Int](a @ _):Right[String, Int]
case Left.unapply[String, Int](b @ _):Left[String, Int]
val l: Either[String, Int] = Left("hello")
val r: Either[String, Int] = Right(22)
这会显式丢弃类型信息,使编译器无法推断出它需要什么。我相信 transparent
依赖于传递参数的类型知识,而不是围绕静态定义值的“暗类型魔法”。如果你擦除传递参数的类型,那么失败是公平的吗?
在试验 Scala 3 的元编程功能时,我发现了这个内联匹配问题,我无法解释清楚。
给定一个透明内联方法 eitherTest
,它采用内联 Either[String, Int]
然后 returns String
或 Int
直接使用内联匹配表达式,如果将 eitherTest
的输入显式键入 Left
或 Right
,则一切正常。但是,如果输入被显式键入 Either
的超类型,编译器似乎无法减少匹配表达式。更奇怪的是 eitherTest
的参数本身被键入为 Either
.
这是编译器错误吗?这是预期的行为吗?我很难理解为什么编译器无法解决这个问题。
斯卡斯蒂 link: https://scastie.scala-lang.org/CThqajauRVeJvxvW0uYy4w
代码:
@main def hello: Unit =
workingTest
failingTest
def workingTest: Unit =
val l: Left[String, Int] = Left("hello")
val r: Right[String, Int] = Right(22)
val tl: String = eitherTest(l)
val tr: Int = eitherTest(r)
println(s"$tl :: $tr")
def failingTest: Unit =
val l: Either[String, Int] = Left("hello")
val r: Either[String, Int] = Right(22)
val tl: String = eitherTest(l)
val tr: Int = eitherTest(r)
println(s"$tl :: $tr")
transparent inline def eitherTest(inline v: Either[String, Int]): Any =
inline v match
case Right(a) => a
case Left(b) => b
错误:
cannot reduce inline match with
scrutinee: l : (l : Either[String, Int])
patterns : case Right.unapply[String, Int](a @ _):Right[String, Int]
case Left.unapply[String, Int](b @ _):Left[String, Int]
val l: Either[String, Int] = Left("hello")
val r: Either[String, Int] = Right(22)
这会显式丢弃类型信息,使编译器无法推断出它需要什么。我相信 transparent
依赖于传递参数的类型知识,而不是围绕静态定义值的“暗类型魔法”。如果你擦除传递参数的类型,那么失败是公平的吗?