是否有一个类型类检查至少一个类型隐式的存在?

jbwheatley

我有一个特点Foo[T, U]和类型层次的算法,给出了L <: HList和目标类型U,告诉我,是否存在TL这样的,有一个隐含的Foo[T, U]范围。这是使用以下类型类实现的:

trait Search[L <: HList, U]

object Search {
  def apply[L <: HList, U](implicit s: Search[L, U]): U = null

  ...
}

我们有以下内容:

object Test {
  type L = Int :: String :: HNil

  implicit val foo: Foo[String, Boolean] = null

  Search[L, Boolean] //compiles

  Search[L, Double] //does not compile
}

我想是关于搜索在所有不会发生,如果没有Foo[T, U]任何T的所有范围,因为这时我们已经知道,该算法将无法完成。换句话说,我想要一个类型类trait Exists[F[_]],当且仅当F范围中至少隐含一个实例时,该实例才会存在实例,因此该函数Search.apply具有签名:

def apply[L <: HList, U](implicit ev: Exists[Foo[_, U]], s: Search[L, U]): U = null

在这种情况下,编译器将仅尝试解析范围中s是否存在任何隐式Foo

是否可以定义这种类型的类?是否已经存在?

米米(Dmytro Mitin)

尝试

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

trait Exists[A]

object Exists {
  implicit def materialize[A]: Exists[A] = macro impl[A]

  def impl[A: c.WeakTypeTag](c: blackbox.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 tpA = weakTypeOf[A]

    val searchResult = analyzer.inferImplicit(
      tree = EmptyTree.asInstanceOf[global.Tree],
      pt = tpA.asInstanceOf[global.Type],
      reportAmbiguous = false,
      isView = false,
      context = callsiteContext,
      saveAmbiguousDivergent = true,
      pos = c.enclosingPosition.asInstanceOf[global.Position]
    )

    val isAmbiguous = callsiteContext.reporter.firstError match {
      case Some(analyzer.AmbiguousImplicitTypeError(_,_)) => true
      case _ => false
    }

    if (searchResult.isSuccess || searchResult.isAmbiguousFailure || isAmbiguous) 
      q"new Exists[$tpA] {}"
    else c.abort(c.enclosingPosition, s"no implicit $tpA")    
  }
}

测试

// no implicit Int
// implicitly[Exists[Int]] // doesn't compile

implicit val i: Int = 1 
implicitly[Exists[Int]] // compiles

implicit val i: Int = 1 
implicit val i1: Int = 2 
implicitly[Exists[Int]] // compiles

我想原来Search

trait Foo[U, V]

trait Search[L <: HList, V]

trait LowPrioritySearch {
  implicit def tail[H, T <: HList, V](implicit search: Search[T, V]): Search[H :: T, V] = null
}

object Search extends LowPrioritySearch {
  def apply[L <: HList, U](implicit s: Search[L, U]): U = null.asInstanceOf[U]

  implicit def head[U, T <: HList, V](implicit foo: Foo[U, V]): Search[U :: T, V] = null
}

现在用 Exists

def apply[L <: HList, U](implicit ev: Exists[Foo[_, U]], s: Search[L, U]): U = null.asInstanceOf[U]

也可以

Search[L, Boolean] //compiles
// Search[L, Double] //does not compile

在2.13.0中测试

libraryDependencies ++= Seq(
  scalaOrganization.value % "scala-reflect" % scalaVersion.value,
  scalaOrganization.value % "scala-compiler" % scalaVersion.value
)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何检查基本类型列表是否至少包含某些子类型的一个实例

是否可以为除了一个类型子集之外的所有类型都可以使用的特征创建一个通用的隐式?

检查列表是否包含另一个列表中存在的所有类型的元素

是否有一种优雅的方法来检查至少一个元素是否具有某个类?

如何检查一个类型是否是另一个类型的子类?

使用typetag检查一个类型是否是另一个的超类型

隐式有一个 `any` 类型因为索引表达式不是类型 'number'.ts(7015)

如何检查一个类是否存在

使用 eslint-plugin-flowtype,如何检查一个类型是否存在

如何检查一个类是否为java.lang.Number类型

类型检查参数是一个(子)类,并且还实现了一个接口

有没有办法检查一个类中是否存在函数?

单线检查列表中是否至少有一个项目存在于另一个列表中?

打字稿:定义一个接口/类型,其中至少存在两个属性之一(也可以同时存在)

jQuery检查一个元素中是否有多个类(必须全部存在)

检查2个数组是否至少有一个共同的元素?

检查两个 Python 集合是否至少有一个公共元素

为什么C ++运算符重载需要“至少具有一个类类型的参数”?

检查是否存在至少一个字符串列表中

如何检查数组是否包含至少一个对象?

检查数组是否包含至少一个元素-Angular

检查至少一个列表是否包含特定元素

要求至少一个给定类型的属性

如何检查一个对象是否至少有一条记录?

Scala:如何检查是否至少定义了一个类的字段?

将一个类的对象隐式转换为另一个类

我可以隐式创建一个可复制的类型吗

是否有一个类型为Show Int的值?

AS3中是否有一个类可以告诉您URL协议的类型?