输入参数化算术?

时间:2011-07-07 15:20:42

标签: 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 hours = 2[Hour]
val minutes = 5[Minute]
val result = hours - minutes
assert (result == 115[Minute])

这样的事情是否存在,它是否有用,是否可以实现?

编辑:澄清一下,上面的时间示例只是我想到的一个随机例子。我的问题更多的是,参数化数字的概念是否是一个有用的概念,就像你有参数化列表等(答案可能是“不”,我不知道!)

4 个答案:

答案 0 :(得分:6)

您可以通过为小时和分钟设置两个课程以及从小时到分钟的隐式转换功能来实现此目的

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)

答案 1 :(得分:3)

您可以在电梯框架(spec)中找到一些示例。

import net.liftweb.utils.TimeHelpers._
3.minutes == 6 * 30.seconds

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

答案 2 :(得分:2)

您可以尝试scala-time,这是Joda Time的包装,并使其更加惯用于Scala,包括一些用于进行时间段计算的DSL,类似于Brian Agnew在其答案中建议的内容

例如,

2.hours + 45.minutes + 10.seconds

创建一个Joda Period

答案 3 :(得分:1)

在我看来,DSL会在这里使用。所以你可以写

2.hours - 5.minutes

并进行适当的转换,将2小时转换为小时对象(值2)等。

存在大量描述Scala DSL功能的资源。例如see this from O'Reilly