Scala 类型参数化算法?

Scala 类型参数化算法?,scala,types,functional-programming,parameterized,Scala,Types,Functional Programming,Parameterized,想办法从2小时中减去5分钟 从2中减去5是没有意义的,因为我们最终得到了-3个通用时间单位,这是无用的。但如果“小时”是“分钟”的一个子类型,我们可以将2小时转换为120分钟,得到115分钟,或1小时55分钟 类似地,如果我们想在5个橙子中添加5个苹果,我们无法用苹果来评估,但最终可能会得到10个水果 在上面的例子中,通常当使用数字作为形容词时,整数需要根据它们所描述的对象类型进行参数化。我认为,如果不是宣布 val hours = 2 val minutes = 5 你可以这样做 val h

想办法从2小时中减去5分钟

从2中减去5是没有意义的,因为我们最终得到了-3个通用时间单位,这是无用的。但如果“小时”是“分钟”的一个子类型,我们可以将2小时转换为120分钟,得到115分钟,或1小时55分钟

类似地,如果我们想在5个橙子中添加5个苹果,我们无法用苹果来评估,但最终可能会得到10个水果

在上面的例子中,通常当使用数字作为形容词时,整数需要根据它们所描述的对象类型进行参数化。我认为,如果不是宣布

val hours = 2
val minutes = 5
你可以这样做

val hours = 2[Hour]
val minutes = 5[Minute]
val result = hours - minutes
assert (result == 115[Minute])
这样的东西是否存在,是否有用,是否可以实现


编辑:为了澄清,上面的时间示例只是我想出的一个随机示例。我的问题更多的是,一般来说,参数化数字的概念是否是一个有用的概念,正如你有参数化列表等(答案可能是“否”,我不知道!)

你可以在lift框架()中找到一些例子


(注意:似乎您需要合理的数字来进行正确的比较。例如,可能不会超过60秒。)

在我看来,DSL在这里很有用。这样你就可以写作了

2.hours - 5.minutes
并进行适当的转换,将2小时转换为小时对象(值2)等


有很多资源描述Scala的DSL功能。e、 g.

您可以通过两个小时和分钟的类,以及从小时到分钟的隐式转换函数来实现这一点

trait TimeUnit
case class Hour(val num: Int) extends TimeUnit      
case class Minute(val num: Int) extends TimeUnit {
  def - (sub: Minute) = Minute(num - sub.num)
}

implicit def hour2Minute(hour: Hour) = Minute(hour.num * 60)
这允许您执行以下操作

val h = Hour(2) - Minute(30) //returns Minute(90)
您可以尝试一下,这是一个包装器,它使Scala更加惯用,包括一些DSL来进行时间段计算,类似于Brian Agnew在他的回答中所建议的

比如说,

2.hours + 45.minutes + 10.seconds

创建一个Joda
Period

它可以而且已经用多种语言完成。但是没有关于Scala的线索:)答案建议您使用类似于
3.minutes
的构造,它可能返回某种计时类型的实例。如果您想朝这个方向发展,您可能想看看“Scala Joda Time”库,它是一个围绕Java Joda Time的Scala包装器。但您的示例看起来更像是希望为此创建一个typeclass,例如:
trait TimeValue[TimeUnit]
,其中
TimeUnit
是幻影类型。这对我来说非常有趣,因为它可能也适用于其他单位度量。我不知道是否可以做到。这通常被称为单位或度量。用适当的术语再查一遍——这里有相关的库,还有很多以前的讨论。这里有一个讨论:您需要编写
2.hours
(2 hours)
,否则编译器会假定
-
是一个参数而不是一个方法。正确的答案是“查找“度量单位”,但接受这一点是因为它很有用并且符合大众的需求
2.hours + 45.minutes + 10.seconds