使用Scala的结构类型创建更具体的隐式
据我所知,集合库中没有共享特征来定义map方法(很可能是因为map有不同的签名).
我有一个可观察的值(想想一个ui系统中的属性),它有一个change事件.可以使用map方法映射可观察值. 但是,当我们使用已经有map方法的类型时,我们应该能够使用map的内置方法. 所以代替: prop map { x => x map { actualX => //do something } } 我想这样使用它: prop map { actualX => //do something } 我有一个简化的测试用例.首先是我使用的不同部分: // leaving out the observable part trait ObservableValue[T] { def value: T } trait LowerPriorityImplicits { // default implementation that adds a regular map method implicit class RichObservableValue1[A](o: ObservableValue[A]) { def map[B](f: A => B): ObservableValue[B] = new ObservableValue[B] { def value = f(o.value) } } } object ObservableValue extends LowerPriorityImplicits { // describe a type that has a map method type HasMapMethod[A,Container[X]] = { def map[B](f: A => B): Container[B] } // complex implementation that uses the builtin map if present implicit class RichObservableValue2[A,Container[Z] <: HasMapMethod[Z,Container]]( o: ObservableValue[Container[A]]) { def map[B](f: A => B): ObservableValue[Container[B]] = new ObservableValue[Container[B]] { def value = o.value.map(f) } } } 如果上面的代码有问题(或许有很多),请告诉我.我想这样使用它: class TestCase extends ObservableValue[Option[Int]] { def value = None } val x = new TestCase x map { value => // this fails because the compiler finds the lower priority implicit (value: Int).toString } // the method itself works fine ObservableValue.RichObservableValue2(x) map { value => (value: Int).toString } 如果我将Container [B]更改为Any,它将找到RichObservableValue2隐式转换. 关于如何使用类型来选择含义的我的知识是有限的. 我试图在以下位置找到答案,但主题有点压倒性: > Where does Scala look for implicits? 无论如何要解决这个挑战吗? 编辑 我知道集合的FilterMonadic特性.我正在寻找一种解决方案来识别Option类中定义的map方法. 编辑2 似乎FilterMonadic变体也不起作用.我将RichObservableValue3添加到RichObservableValue对象. implicit class RichObservableValue3[A,C[Z] <: FilterMonadic[Z,C[Z]]](o: ObservableValue[C[A]]) { def map[B,That](f: A => B)(implicit bf: CanBuildFrom[C[A],B,That]): ObservableValue[That] = new ObservableValue[That] { def value = o.value.map(f) val change = o.change map (_ map f) } } 而且,虽然List [Int]是有效的参数,但是并未选择隐式转换.我必须遗漏一些在选择含义时使用的规则. 解决方法
我终于找到了我失踪的部分.为了使隐式匹配,我必须添加以下类型参数:
T[Dummy <: Container[_]] <: ObservableValue[Dummy] 结果对象: object ObservableValue { implicit class Mappable[A](o: ObservableValue[A]) { def map[B](f: A => B): ObservableValue[B] = new ObservableValue[B] { def value = f(o.value) } } // FMC = FilterMonadicContainer // D = Dummy implicit class FilterMonadicMappable[A,FMC[D] <: FilterMonadic[D,FMC[D]]](o: ObservableValue[FMC[A]]) { def map[B,That](f: A => B)(implicit bf: CanBuildFrom[FMC[A],That]): ObservableValue[That] = new ObservableValue[That] { def value = o.value.map(f) } } type HasMap[A,That[_]] = { def map[B](f: A => B): That[B] } // OVC = ObservableValueContainer // MC = MappableContainer // D = Dummy implicit class SimpleMappable[A,MC[D] <: HasMap[D,MC],OVC[D <: MC[_]] <: ObservableValue[D]](o: OVC[MC[A]]) { def map[B](f: A => B): ObservableValue[MC[B]] = new ObservableValue[MC[B]] { def value = o.value.map(f) } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |