【问题标题】:Type inference/type checking failure while using type-level computations使用类型级计算时类型推断/类型检查失败
【发布时间】:2011-12-12 20:49:15
【问题描述】:

我在使用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]

(很抱歉没有在这里粘贴整个代码,它太多了。我试图最小化我的示例,但我失败了。这就是我只是链接到它的原因。)

【问题讨论】:

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


    【解决方案1】:

    Subtractable 中的 Sub 类型在 MInt 特征中缺失。使其工作的一个简单定义是,当您想要减去 MSuccMNeg 中的类型时执行负加法。

    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
    }
    

    还有一点,Quantity 中的/ 方法应该对其参数进行除法而不是相乘!

    【讨论】:

    • 是的,这就是修复。我已将这两个修复提交给 MetaScala 存储库。
    猜你喜欢
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 1970-01-01
    • 2020-12-30
    • 1970-01-01
    相关资源
    最近更新 更多