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

找到两个Scala类型的最常见子类型

发布时间:2020-12-16 18:51:36 所属栏目:安全 来源:网络整理
导读:沿着 this question行,我试图找到一种方法让Scala编译器推断出两种类型A和B的最大公共子类型. 类似“A without B”的东西,其定义是: (A without B = C) === (A = C with B) 或者返回C的类型函数,其中: 编辑: A : C C :! B 即. A是C的子类型,C不是B的子类
沿着 this question行,我试图找到一种方法让Scala编译器推断出两种类型A和B的最大公共子类型.

类似“A without B”的东西,其定义是:

(A without B = C) === (A = C with B)

或者返回C的类型函数,其中:

编辑:

A <: C && C <:!< B

即. A是C的子类型,C不是B的子类型

事实上,我希望有人会指出这与“最常见的子类型”不同,因为我实际上并不需要A<:B. 用法:

trait Syntax

trait ANYSYNTAX extends Syntax
trait NUMERIC extends ANYSYNTAX
trait DISCRETE extends ANYSYNTAX
trait POSITIVE extends ANYSYNTAX
trait CONST extends ANYSYNTAX     
type NUMCONST = NUMERIC with CONST
type POSCONST = POSITIVE with CONST
type ORDINALCONST = DISCRETE with CONST
type INTEGER = NUMERIC with DISCRETE
type POSNUM = POSITIVE with NUMERIC
type POSINT = POSNUM with INTEGER
type INTCONST = INTEGER with NUMCONST with ORDINALCONST
type POSNUMCONST = POSNUM with POSCONST with NUMCONST
type POSINTCONST = POSNUMCONST with INTCONST with POSINT

然后我希望能够传播类型约束,如下所示:

abstract class Expression[+R]( val args: Expression[_]* )

case class Add[A <: R,R <: NUMERIC]( arg1: Expression[A],arg2: Expression[A] ) extends Expression[R] {
case class Subtract[A <: R,R : A without POSITIVE]( arg1: Expression[A],arg2: Expression[A] ) extends Expression[R] {
case class Multiply[A <: R,arg2: Expression[A] ) extends Expression[R]{
case class Divide[A <: R,R : A without DISCRETE]( arg1: Expression[A],arg2: Expression[A] ) extends Expression[R] {

我一直在尝试使用从其他SO答案中借用的某些类型约束来提出一些东西:

sealed class =!=[A,B]

trait LowerPriorityImplicits {
  implicit def equal[A]: =!=[A,A] = sys.error("should not be called")
}
object =!= extends LowerPriorityImplicits {
  implicit def nequal[A,B](implicit same: A =:= B = null): =!=[A,B] =
    if (same != null) sys.error("should not be called explicitly with same type")
    else new =!=[A,B]
}

// Encoding for "A is not a subtype of B"
trait <:!<[A,B]

// Uses ambiguity to rule out the cases we're trying to exclude
implicit def nsub[A,B] : A <:!< B = null
implicit def nsubAmbig1[A,B >: A] : A <:!< B = null
implicit def nsubAmbig2[A,B >: A] : A <:!< B = null

我有一些测试用例:

implicitly[POSINT <:!< CONST]
implicitly[POSITIVE <:!< OPINION]
implicitly[DOGMA <:!< CONST]

implicitly[POSINTCONST <:< POSITIVE with CONST]
implicitly[POSINTCONST <:< POSCONST]
implicitly[POSITIVE with CONST <:!< POSINTCONST]

implicitly[POSITIVE =:= POSCONST without CONST]
implicitly[NUMERIC =:= INTEGER without DISCRETE]
implicitly[POSINT =:= POSINTCONST without CONST]

这些应该失败:

implicitly[POSINT =:= POSINTCONST without OPINION]
implicitly[POSINT with OPINION =!= POSINTCONST without OPINION]

解决方法

听起来你想要一个scala类型的最小上界(LUB)?我会向Miles的无形图书馆寻找灵感,他们实际拥有 LUBConstraint.

或者如果你想要更大的下界(GLB)我恐怕我不得不推荐你使用宏定义,你可以得到LUB或GLB,见Types.

(编辑:李大同)

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

    推荐文章
      热点阅读