Scala3 opaque type隐式转换失效问题(实际非其导致)
Scala高阶Opaque类型与隐式转换问题
**编辑2 开始:**我之前未验证示例中的转换对普通类型是否生效,结果发现也不生效。因此标题及整个帖子内容有误,抱歉,是否应删除?编辑2 结束:
Sheet1类的设计目标是将值存储在无类型容器中,但以类型安全的方式操作。
class Sheet1 { opaque type Ref[X] = Int; private val cells: ArrayBuffer[Any] = ArrayBuffer.empty; def addCell[A](a: A): Ref[A] = { val ref = cells.size; cells.addOne(a); ref } def update(map: Map[Ref[?], Any]): Unit = // 编译失败:不可化简的高阶类型Ref应用于通配符参数 map.foreachEntry { (k, v) => cells(k) = v } }
但编译器报错:"不可化简的高阶类型Ref应用于通配符参数"。我搜索该报错信息但未找到解决方案。
**编辑 开始:**我现在知道可以用类型参数替换通配符来避免该错误:
def update[X](map: Map[Ref[X], Any]): Unit
但这需要将Ref设为协变(本不应如此)。假设我更倾向于用隐式转换解决问题,于是尝试了另一种方案:
编辑 结束
新增一个普通opaque type Reference,将方法签名中的通配符opaque type Ref[X]替换为Reference,并添加二者间的隐式转换。
class Sheet2 { opaque type Reference = Int; opaque type Ref[X] = Reference; private val cells: ArrayBuffer[Any] = ArrayBuffer.empty; def addCell[A](a: A): Ref[A] = { val ref = cells.size; cells.addOne(a); ref } given refToReference[T]: Conversion[Ref[T], Reference] = identity; // given refMapToReferenceMap[K, V]: Conversion[Map[Ref[K], V], Map[Reference, Any]] = identity def update(map: Map[Reference, Any]): Unit = map.foreachEntry { (k, v) => cells(k) = v } }
该方案避免了“不可化简的高阶类型Ref应用于通配符参数”问题,编译通过,但使用时隐式转换失效:
object User { val sheet = new Sheet2; import sheet.* val listRef: Ref[List[Int]] = sheet.addCell(List(1,2,3)); import scala.language.implicitConversions; import sheet.refToReference; // 非必需,仅作尝试 sheet.update(Map((listRef: Reference) -> List(3,2,1))); // 使用类型归属可正常运行 sheet.update(Map(refToReference(listRef) -> List(3,2,1))); // 显式调用转换器可正常运行 val x = Map(refToReference(listRef) -> List(3,2,1)) sheet.update(x); // 使用中间变量可运行,但需取消注释refMapToReferenceMap转换 sheet.update(Map(listRef -> List(3,2,1))); // 尝试隐式转换失败,报错:找到(sheet.Ref[List[Int]], List[Int]); 需(sheet.Reference, Any) }
我哪里出错了?
已在scalaVersion "3.1.3"和"3.2.1"中测试,结果一致。
内容的提问来源于stack exchange,提问作者Readren
相关产品推荐
相关产品推荐

