使用类型级计算时键入推断/类型检查失败

时间:2011-10-21 19:56:30

标签: generics scala types alias units-of-measurement

我在使用文件metascala中定义的Units.scala中的度量单位功能时遇到了问题。

对于本问题的其余部分,我将使用简化方案,只有一种单位类型,长度。

所以现实中的类型看起来像是

Quantity[_1, _0, _0, _0, _0, _0, _0] 
          ^   ^   ^   ^   ^   ^   ^
          |   |   |   |   |   |   |
          | Mass  | Crncy.|  Mol  |
       Length   Time    Temp. Lum.Intensity

这足以证明问题:

Quantity[_1]
          ^
          |
       Length

只要需要推断出类型,麻烦就会开始。

考虑这个例子(也看一下UnitsTest.scala的代码):

val length: Quantity[_1] = m(5)
val area:   Quantity[_2] = length * length // (1) Works
val dist:   Quantity[_1] = area / length   // (2) Doesn't work!

我在最后一行收到错误说:

type mismatch;
  found :
    scalax.units.Units.Quantity[
      scalax.units.Subtractables.-[
        scalax.units.Integers._2,
        scalax.units.Integers._1
      ]
    ]

  required:
    scalax.units.Units.Quantity[
      scalax.units.Integers._1
    ]

当“减去维度”时,看起来编译器无法弄清楚当前的类型等于Quantity[_1],例如。 G。像(1)中那样从一个区域到另一个区域:

Quantity[_2 - _1] <<not equal to>> Quantity[_1]

令人困惑的是,它在“添加维度”时有效。 G。像(2)中那样从长度变为区域:

Quantity[_1 + _1] <<equal to>> Quantity[_2]

(很抱歉没有粘贴整个代码,这太过分了。我试图最小化我的例子,但我失败了。这就是为什么我只是链接到它。)

1 个答案:

答案 0 :(得分:2)

Sub特征中缺少来自Subtractable的{​​{1}}类型。如果要在MIntMSucc中减去类型,则可以使其有效的简单定义是执行否定添加。

MNeg

还有一件事,sealed trait MInt extends Visitable[IntVisitor] with Addable with Subtractable { type AddType = MInt type SubType = MInt type Add[I <: MInt] <: MInt type Sub[I <: MInt] <: MInt type Neg <: MInt type Succ <: MInt type Pre <: MInt } final class _0 extends Nat { type Add[I <: MInt] = I type Sub[I <: MInt] = I#Neg type AcceptNatVisitor[V <: NatVisitor] = V#Visit0 type Neg = _0 type Succ = MSucc[_0] type Pre = Succ#Neg } final class MSucc[P <: Nat] extends Pos { type This = MSucc[P] type Add[N <: MInt] = P#Add[N]#Succ type Sub[N <: MInt] = Add[N#Neg] type AcceptNatVisitor[V <: NatVisitor] = V#VisitSucc[P] type Neg = MNeg[This] type Pre = P type Succ = MSucc[This] } final class MNeg[P <: Pos] extends MInt { type Add[N <: MInt] = P#Add[N#Neg]#Neg type Sub[N <: MInt] = Add[N#Neg] type Accept[V <: IntVisitor] = V#VisitNeg[P] type Neg = P type Succ = P#Pre#Neg type Pre = P#Succ#Neg } 中的/方法应该划分其参数而不是将它们相乘!