You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:21:36