加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

带有子类型的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 |一个.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读