2012-03-09 28 views
2

我想要做的是定义条件的类,包括继承。如果有两个条件(或or-ed),则结果应该是更具体的类的条件,即查询条件。 所以,如果我有斯卡拉类型推理,并获得更具体的两种类型参数作为方法结果

class Parent 
class Sub extends Parent 
class SubSub extends Sub 

一个Condition[Sub] and Condition[Parent] and Condition[SubSub]应该产生一个Condition[SubSub]。 条件也应该是不相容的,因为父母的条件也应该是子条件。因此,我定义(在AnyRef是一个额外的,外部约束):

class Condition[-A<:AnyRef] { 
    def and[R<:A, P>:R<:AnyRef](that:Condition[P]):Condition[R]= 
    new AndCondition[R](this, that) 
} 

class AndCondition[-A<:AnyRef](left:Condition[_>:A], right:Condition[_>:A]) 
    extends Condition[A] 

的AndCondition的打字似乎是确定的,因为这

val a:AndCondition[SubSub] = 
    new AndCondition(
    new AndCondition(
     new AndCondition(
     new Condition[Parent], 
     new Condition[Sub]), 
     new Condition[Parent]), 
    new Condition[SubSub]) 

作品。我曾与和方法问题,中缀通话和上述定义,也可以工作上来:

val b: Condition[SubSub] = 
    new Condition[Parent] and 
    new Condition[SubSub] and 
    new Condition[Sub] 

...样的,因为它停止和荷兰国际集团第四条件时工作:

val c: Condition[SubSub]= 
    new Condition[Parent] and 
    new Condition[SubSub] and 
    new Condition[Sub] and 
    new Condition[Parent] 

结果在“无”推论:

error: inferred type arguments 
[com.solvedirect.test.SubSub,com.solvedirect.test.SubSub,com.solvedirect.test.Parent] 
do not conform to method and's type parameter bounds 
[R <: Nothing,R <: R,P >: R <: AnyRef] 

“减少”该“和链”由第一和第二两个条件支撑在一起(即(a和b)和(c和d)),使它再次编译。 我想我采取了一些错误的路线,但看不到它。对于不具体的问题标题,或者已经回答了这个问题,我很抱歉,但是我找不到它,可能也是由于缺乏描述性搜索条款。

谢谢你的时间。

问候,

梅西

+0

我现在试着用相交结果类型定义'和'方法如下: 'def和[P <:AnyRef](that :条件[P]):条件[A与P] =新AndCondition [A与P](这,那)' 这似乎工作,但我不确定这是否具有意想不到的副作用。 – messi 2012-03-10 13:36:51

回答

0

所有我想提出的事实,具有无法推断通用参数是怪异你的注意,因为不包含有关数据的任何信息的第一包含在课堂上。如果会的话,那么它将是可以推断的。

当您不明确指定返回类型时,可以推断出一个参数。由于管道符(除非他们与斯卡拉:)最后是左关联的,在此声明:

val c:Condition[SubSub] = new Condition[Parent] and new Condition[SubSub] and 
    new Condition[Sub] and 
    new Condition[Parent] 

编译器的行为是这样的:

((new Condition[Parent] and new Condition[SubSub]) and 
    new Condition[Sub]) and 
    new Condition[Parent]) 

所以你在下列情况下结束:

  • 第一和条件[家长]和条件之间[SubSub]返回不能推断出你没有指定类型,因此它是UnknownType1
  • 第二个也是一样:它是UnknownType1和Condition [Sub]之间的一个,返回UnknownType2
  • 第三个接受UnknownType2和Condition [Parent]。这里编译器不能检查约束保持。

请注意的是,在三个操作数的情况下,和:

val b: Condition[SubSub] = 
new Condition[Parent] and 
    new Condition[SubSub] and 
    new Condition[Sub] 

编译器使用B的类型来推断中间结果(家长和SubSub)的种类和可以检查界限。

在失败的情况下,编译器需要推断两次结果,并且不能这样做。

要回到最初的评论,也请注意,在简单的情况下,如果不指定结果,编译器也将失败,这是正常的你的类设计不良的标志

val e = new Condition [Parent] and new Condition [SubSub]