为什么此隐式解析失败? [英] Why is this implicit resolution failing?

查看:53
本文介绍了为什么此隐式解析失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面进行了一个隐式转换-感觉它应该确实可以工作,但绝对不能.谁能阐明任何想法?我知道隐式有时在使用类型细化时可能会失败-这是这里的问题吗?

I have an implicit conversion - below - which feels like it should definitely be working but is definitely not. Can anyone shed any light? I know implicitly can sometimes fail when type refinements are used - is that the issue here?

trait GetItem[A[_], T, R] {
  type Out
  def ret(a: A[T], ref: R): Out
}
object GetItem {
  implicit def ifRefIsInt[A[_], T]: GetItem[A, T, Int] { type Out = A[T] } = new GetItem[A, T, Int] {
    type Out = A[T]
    def ret(a: A[T], ref: Int): Out = a
  }
}
import GetItem._
//this works fine:
val t: GetItem[List, Double, Int] { type Out = List[Double] } = ifRefIsInt[List, Double]
// so does this:
implicitly[GetItem[List, Double, Int] { type Out = List[Double] }](t)
// this does not:
implicitly[GetItem[List, Double, Int] { type Out = List[Double] }] 
// Could not find implicit parameter for value e: Example.Main.GetItem[List, Double, Int]{type Out = List[Double]}

任何帮助,我一直在盯着它看,但收效甚微.

Any help much appreciated, I have been staring at this for some time with little success.

推荐答案

似乎是过度约束隐式对象的另一个示例( 2 3 4 6 ).在一个步骤中,对于隐式而言,这似乎是太多的工作.编译器不喜欢(A,B) H :: L A [T] 这样的复杂类型(在我们的示例中)在类型改进中.如果我们替换

Seems to be another example of over-constrained implicits (1 2 3 4 5 6). This seems to be too much work for implicits in a single step. Compiler doesn't like complex types like (A, B), H :: L, and A[T] (in our case) in a type refinement. If we replace

implicit def ifRefIsInt[A[_], T]: GetItem[A, T, Int] { type Out = A[T] } = 
  new GetItem[A, T, Int] {
    type Out = A[T]
    def ret(a: A[T], ref: Int): Out = a
  }

使用

implicit def ifRefIsInt[A[_], T, O](implicit 
  ev: A[T] =:= O
): GetItem[A, T, Int] { type Out = O } = new GetItem[A, T, Int] {
  type Out = O
  def ret(a: A[T], ref: Int): Out = a
}

然后

implicitly[GetItem.Aux[List, Double, Int, List[Double]]]
implicitly[GetItem[List, Double, Int] { type Out = List[Double] }]

编译: https://scastie.scala-lang.org/P5iXP2ZfQUCKEIMukYyqIg (斯卡拉2.13.3)

compile: https://scastie.scala-lang.org/P5iXP2ZfQUCKEIMukYyqIg (Scala 2.13.3)

出于某种原因,编译器会吞下警告( -Xlog-implicits 处于打开状态).如果我手动触发隐式搜索

For some reason compiler swallows a warning (with -Xlog-implicits switched on). If I trigger implicit search manually

import scala.language.experimental.macros
import scala.reflect.macros.{whitebox, contexts}

def foo[A]: Unit = macro fooImpl[A]

def fooImpl[A: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
  import c.universe._

  val context = c.asInstanceOf[contexts.Context]
  val global: context.universe.type = context.universe
  val analyzer: global.analyzer.type = global.analyzer
  val callsiteContext = context.callsiteTyper.context

  val typ = weakTypeOf[A]

  val search = new analyzer.ImplicitSearch(
    tree = EmptyTree.asInstanceOf[global.Tree],
    pt = typ.asInstanceOf[global.Type],
    isView = false,
    context0 = callsiteContext.makeImplicit(reportAmbiguousErrors = true),
    pos0 = c.enclosingPosition.asInstanceOf[scala.reflect.internal.util.Position]
  )

  println(s"allImplicits=${search.allImplicits}")

  q""
}

然后

foo[GetItem[List, Double, Int] { type Out = List[Double] }]

发出警告

App.this.GetItem.ifRefIsInt is not a valid implicit value for App.GetItem[List,Double,Int]{type Out = List[Double]} because:
hasMatchingSymbol reported error: polymorphic expression cannot be instantiated to expected type;
 found   : [A[_], T]App.GetItem[A,T,Int]{type Out = A[T]}
 required: App.GetItem[List,Double,Int]{type Out = List[Double]}

scalac: allImplicits=List()

即无法推断 A T .

这篇关于为什么此隐式解析失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆