我正在尝试扩展Miles Sabin在这篇出色的文章中描述的功能:Unboxed Union Types以支持n一元类型的并集,例如:]]
def if[T](t: T)(implicit ev: T <<: (Int | String | Symbol | Double)): String = ???
我修改了Sabin的代码,并编写了自己的
<:<
运算符版本,如下所示。
object UnboxedTypeUnion extends TypeUnion { def is[T](t: T)(implicit ev: T <<: (Int | String | Double | Symbol)) = t match { case _: Int => "int" case _: String => "string" case _: Double => "double" case _: Symbol => "symbol" } // Does not compile val x = implicitly[Int <<: (Int | String | Double)] val y = implicitly[Int <<: Not[Not[Not[Not[Int]]]]] } trait TypeUnion { type Not[A] = A => Nothing type |[A, B] = Not[Not[A] with Not[B]] sealed abstract class <<:[-A, +B] extends (A => B) object <<: { val singleton = new <<:[Any, Any] { override def apply(v1: Any): Any = v1 } implicit def instance[A]: A <<: A = singleton.asInstanceOf[A <<: A] implicit def negation[A]: A <<: Not[Not[A]] = singleton.asInstanceOf[A <<: Not[Not[A]]] implicit def transitivity[A, B, C](implicit ab: A <<: B, bc: B <<: C): A <<: C = singleton.asInstanceOf[A <<: C] } }
潜在的问题是,每个附加的逻辑析取(
OR
)将结果的证据子类包装为新的双重否定,即
implicitly[Not[Not[Int]] <<: (Int | String)] implicitly[Not[Not[Not[Not[Int]]]] <<: (Int | String | Double )] implicitly[Not[Not[Not[Not[Not[Not[Int]]]]]] <<: (Int | String | Double | Symbol )] // etc.
从理论上讲,我希望双重否定身份的定义与及物性的定义相结合,以使其能够起作用,但是我无法对其进行编译。有谁知道这是否可行,或者递归链接的泛型是否超出了Scala编译器的功能?
我正在尝试扩展Miles Sabin在这篇出色文章中描述的功能:Unboxed Union Types以支持n元类型的并集,例如:def if [T](t:T)(隐式ev:T << [