首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >子类型以外的二义性隐式解决方案

子类型以外的二义性隐式解决方案
EN

Stack Overflow用户
提问于 2017-12-10 08:09:34
回答 1查看 93关注 0票数 3

如果你运行下面的代码,你会得到一个ambiguous implicit错误:

代码语言:javascript
复制
class Foo[T,I](val msg: I)
object Foo {
  implicit def provide[T]: Foo[T,String] =
    new Foo("I came from a place you can't touch so subtyping can't help you")
}

class User
object User {
  implicit object userFoo extends Foo[User,Int](42)
}

def fooOf[T,I](U: T)(implicit foo: Foo[T,I]): Foo[T, I] = foo

fooOf(new User).msg //epic fail:
//Error:(232, 7) ambiguous implicit values:
//both object userFoo in object User of type A$A153.this.User.userFoo.type
//and method provide in object Foo of type [T]=> A$A153.this.Foo[T,String]
//match expected type A$A153.this.Foo[A$A153.this.User,I]
//fooOf(new User).msg;//
//^

通常,Scala会将F[T,I]中类型为T的伴生对象优先于F[_]中的伴生对象,但在这种情况下并非如此,因为两个定义位置中的I类型不同(如果它们都是String,Scala会选择User伴生对象中的Foo[User,String] )。

我不能(或者更确切地说,不想)接触Foo伴生对象来实现LowerPriorityImplicits子类型技术,并在其中定义更高优先级的F[User,I]实例。我还能做什么?

EN

回答 1

Stack Overflow用户

发布于 2017-12-10 08:45:46

我找到了一个解决方案,允许函数fooOf只显式地在伴生对象中查找:

代码语言:javascript
复制
sealed trait ILevel
case object FooLevel extends ILevel
case object CompanionLevel extends ILevel

abstract class Foo[T,I](val msg: I) {
  type Level <: ILevel
}
object Foo {
  implicit def provide[T]: Foo[T,String] =
    new Foo[T,String]("I came from a place you can't touch so subtyping can't help you") {
      override type Level = FooLevel.type
    }
}

class User
object User {
  implicit object userFoo extends Foo[User,Int](42) {
    type Level = CompanionLevel.type
  }
}

type CompanionLevelFoo[T,I] = Foo[T,I] {type Level = CompanionLevel.type }

def fooOf[T,I](U: T)(implicit tc2: CompanionLevelFoo[T,I]): Foo[T, I] = tc2

fooOf(new User).msg 

我一找到就发了。不知道这会带来多大的麻烦。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47734552

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档