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

Scala中@newtype为何导致LUB无法正确推断?

Scala类型推断问题:newtype宏导致List.contains报错

Scala版本:2.13.5

我定义了以下case类:

@derive(decoder, encoder, eqv, show, uuid)
@newtype
case class GenreId(value: UUID)

@derive(decoder, encoder, eqv, show)
case class Genre(
    uuid: GenreId,
    name: GenreName,
    parent: Option[GenreParentId],
    toplevel: Option[GenreTopLevelId],
    idpath: List[GenreId]
)

使用newtype和derevo库,未明确定义的类型均可视为类似GenreId的包装类型,内部为String或UUID。

我定义了如下递归函数:

private[services] def findTopLevel(allGenres: List[Genre], parent: Option[GenreId]): Option[GenreId] = {
  parent match {
    case None => None
    case Some(parentId) =>
       val currentParent: Option[Genre] = allGenres.filter(g => g.uuid.toString() == parentId.value.toString()).headOption
       currentParent.flatMap{ n => 
         n.parent match {
            case None    => Some(n.uuid) 
            case _ @ Some(a) => 
               if(allGenres.contains((x : Genre) => x.uuid.value === a.value)){  
                   findTopLevel(allGenres, Some(GenreId(a.value)))
               }else{
                    Some(n.uuid)
               }
         }
       }
   }
}

运行后出现错误:

[error] a type was inferred to be `Object`; this may indicate a programming error.
[error]                     if(allGenres.contains((x : Genre) => x.uuid.value === a.value)){  

问题根源与contains[A1 >: A](elem: A1): Boolean的签名有关,尽管已有相关讨论,但我认为Iterator同样协变却无此问题。改用filter(...).length或.iterator.contains可正常运行。

随后我发现问题与newtype宏有关,移除该宏后代码可正常运行。

我清楚该宏的展开逻辑,但仍困惑为何类型推断会直接跳到Object,尤其在类型匹配的简单场景中。请问有人知道原因及解决方法吗?


内容的提问来源于stack exchange,提问作者sinanspd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 15:17:37