找到两个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. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |