Miles Sabin によるこの優れた記事で説明されている機能を拡張しようとしています: Unboxed Union Types to support n -ary type unions, 例:
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 コンパイラの機能を超えているかどうかを知っている人はいますか?