generics - 使用类型级计算时类型推断/类型检查失败

标签 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]当“减去一个维度”时,e。 G。从地区到地区,如 (1) :
Quantity[_2 - _1] <<not equal to>> Quantity[_1]

令人困惑的是它在“添加维度”时有效。 G。从长度到面积,如 (2) :
Quantity[_1 + _1] <<equal to>> Quantity[_2]

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

最佳答案

类型 Sub来自 Subtractable MInt 中缺少特征。使其工作的一个简单定义是当您想减去 MSucc 中的类型时执行负加法。和 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
}

还有一件事,/ Quantity 中的方法应该除以它的参数而不是乘以它们!

关于generics - 使用类型级计算时类型推断/类型检查失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7854617/

相关文章:

generics - Kotlin 是否有等效于 C#'s "default"的关键字?

c# - .NET 类型推断 : can't infer usage of "T GetValue<T>(T defaultValue = default(T))"?

scala - 如何在scala上使用表测试?

scala - 什么是 "Call By Name"?

c# - 如何检查变量的类型是否与存储在变量中的类型匹配

vba - 寻找返回 Integer 的 WorksheetFunction 方法

c - 当您在 C 中将两种不同的类型相加时会发生什么?

generics - 收集到Vec与&Vec

java - 从 Realm 中获取通用类型的 Realm 对象

Java 玩!框架开发