带有子类型的scala中的联合类型:A | B <:A | B | C.
发布时间:2020-12-16 18:14:36 所属栏目:安全 来源:网络整理
导读:我想将A | B类型作为A | B | C的子类型.这可能在 Scala中编码吗?如果有,怎么样? 我希望我能隐含地[??[IF]: T]编译如下(原始代码here),但它没有.有没有办法修复此代码以允许子类型? object NUnion{ type ??[A] = ?[?[A]] type ?[A] = A = Nothing trait D
我想将A | B类型作为A | B | C的子类型.这可能在
Scala中编码吗?如果有,怎么样?
我希望我能隐含地[??[IF]<:< T]编译如下(原始代码here),但它没有.有没有办法修复此代码以允许子类型? object NUnion{ type ??[A] = ?[?[A]] type ?[A] = A => Nothing trait Disj[T] { type or[S] = Disj[T with ?[S]] type apply = ?[T] } // for convenience type disj[T] = { type or[S] = Disj[?[T]]#or[S] } type T = disj[Int]#or[Float]#or[String]#apply type IF = disj[Int]#or[Float]#apply implicitly[??[Int] <:< T] // works // implicitly[??[Double] <:< T] // doesn't work // implicitly[??[IF] <:< T] // doesn't work - but it should } 我也试过这个(从here开始): object Kerr{ def f[A](a: A)(implicit ev: (Int with String with Boolean) <:< A) = a match { case i: Int => i + 1 case s: String => s.length } f(1) //works f("bla") // works def g[R]()(implicit ev: (Int with String with Boolean) <:< R):R = "go" // does not work } 但是在这里我不能使联合类型“第一类”它们只能作为参数类型存在,而不能作为返回类型存在. 与this方法相同的问题: object Map{ object Union { import scala.language.higherKinds sealed trait ?[-A] sealed trait TSet { type Compound[A] type Map[F[_]] <: TSet } sealed trait ? extends TSet { type Compound[A] = A type Map[F[_]] = ? } // Note that this type is left-associative for the sake of concision. sealed trait ∨[T <: TSet,H] extends TSet { // Given a type of the form `? ∨ A ∨ B ∨ ...` and parameter `X`,we want to produce the type // `?[A] with ?[B] with ... <:< ?[X]`. type Member[X] = T#Map[?]#Compound[?[H]] <:< ?[X] // This could be generalized as a fold,but for concision we leave it as is. type Compound[A] = T#Compound[H with A] type Map[F[_]] = T#Map[F] ∨ F[H] } def foo[A : (? ∨ String ∨ Int ∨ List[Int])#Member](a: A): String = a match { case s: String => "String" case i: Int => "Int" case l: List[_] => "List[Int]" } def geza[A : (? ∨ String ∨ Int ∨ List[Int])#Member] : A = "45" // does not work foo(geza) foo(42) foo("bar") foo(List(1,2,3)) // foo(42d) // error // foo[Any](???) // error } } 解决方法
Scala.js(
source和
tests)的联合类型支持A | A |的B亚型B | C.它甚至支持像A |这样的排列B的B亚型C |一个.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |