开发者

Type parameterized arithmetic?

Trying to think of a way to subtract 5 minutes from 2 hours.

It doesn't make sense to subtract 5 from 2, because we end up with -3 generic time units, which is useless. But if "hour" is a subtype of "minute", we could convert 2 hours to 120 minutes, and yield 115 minutes, or 1 hour and 55 minutes.

Similarly, if we want to add 5 apples to 5 oranges, we cannot evaluate this in terms of apples, but might expect to end up with 10 fruit.

It seems in the above examples, and generally when using a number as an adjective, the integers need to be parameterized by the type of object they describing. I think it would be very useful if instead of dec开发者_开发技巧laring

val hours = 2
val minutes = 5

you could do something like

val hours = 2[Hour]
val minutes = 5[Minute]
val result = hours - minutes
assert (result == 115[Minute])

Does anything like this exist, would it be useful, and is it something that could be implemented?

EDIT: to clarify, the time example above is just a random example I thought up. My question is more whether in general the idea of parameterized Numerics is a useful concept, just as you have parameterized Lists etc. (The answer might be "no", I don't know!)


You can accomplish this by having two classes for Hours and Minutes, along with an implicit conversion function from hours to minutes

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)

This allows you to do something like

val h = Hour(2) - Minute(30) //returns Minute(90)


You can find some examples for this in the lift framework (spec).

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

(Note: it seems you need to have reasonable numbers for correct comparison. Eg. There may be no more than 60 seconds.)


You might try scala-time, which is a wrapper around Joda Time and makes it a bit more idiomatic for Scala, including some DSL to do time period computations, similar to what Brian Agnew suggested in his answer.

For instance,

2.hours + 45.minutes + 10.seconds

creates a Joda Period.


It seems to me a DSL would be of use here. So you could write

2.hours - 5.minutes

and the appropriate conversions would take place to convert 2 hours into a Hours object (value 2) etc.

Lots of resources exist describing Scala's DSL capabilities. e.g. see this from O'Reilly

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜