這是我在這里遇到的一個相當小眾的問題我懷疑這是一個編譯器錯誤,但是由于我對匹配型別還很陌生,所以我想先在這里問。
import scala.deriving.*
type Flatten[A <: Tuple] <: Tuple = A match
case ((a, b), c) => Tuple.Append[Flatten[(a, b)], c]
case (_, _) => A
case Tuple1[_] => A
case EmptyTuple => EmptyTuple
opaque type MyString = String
object Bar:
opaque type MyString = String
def run =
summon[(MyString, Int) =:= Flatten[(MyString, Int)]]
summon[(Bar.MyString, Int) =:= Flatten[(Bar.MyString, Int)]]
斯卡斯蒂
最后一行編譯失敗,而上面的行(幾乎相同的代碼)編譯成功。但是,當匹配型別中的第一個遞回案例被禁用時,它會起作用。
uj5u.com熱心網友回復:
不是這方面的專家,但我想我可以從中理解:
編譯器錯誤說:
Note: a match type could not be fully reduced:
trying to reduce Playground.Flatten[(Playground.Bar.MyString, Int)]
failed since selector (Playground.Bar.MyString, Int)
does not match case ((a, b), c) => Tuple.Append[Playground.Flatten[(a, b)], c]
and cannot be shown to be disjoint from it either.
Therefore, reduction cannot advance to the remaining cases
由于Bar.MyString
在您的 .x 中實際上是“不透明的” def run
,因此編譯器不知道(或表現得像不知道)它是什么型別。請注意,您不能summon[Bar.MyString =:= String]
from def run
,但可以summon[MyString =:= String]
。
因此,從 inside def run
,后面的實際型別Bar.MyString
可能是 a String
,但也可能是其他型別 - 例如,它可能是(Int, Int)
,在這種情況下case ((a, b), c)
會匹配。所以:編譯器無法確定是否case ((a, b), c)
匹配,因此失敗。
另一方面,MyString
從內部實際上并不是“不透明”的def foo
,因為它是在同一范圍內定義的,所以知道型別是String
,因此知道(MyString, Int)
無法匹配case ((a, b), c)
。
請注意,這確實可以編譯(因為召喚發生在與定義相同的范圍內,Bar.MyString
因此后面的實際型別opaque type
是可見的):
object Bar:
opaque type MyString = String
def runLocally =
summon[(MyString, Int) =:= Flatten[(MyString, Int)]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/508554.html
上一篇:引起:java.io.NotSerializableException:java.util.function.Predicate$$Lambda