Implementing a Measured value in Scala
A Measured value consists of (typically nonnegative) floating-point number and unit-of-measure. The point is to represent real-world quantities, and the rules that govern them. Here's an example:
scala> val oneinch = Measure(1.0, INCH) oneinch : Measure[INCH] = Measure(1.0) scala> val twoinch = Measure(2.0, INCH) twoinch : Measure[INCH] = Measure(2.0) scala> val onecm = Measure(1.0, CM) onecm : Measure[CM] = Measure(1.0) scala> oneinch + twoinch res1: Measure[INCH] = Measure(3.0) scala> oneinch + onecm res2: Measure[INCH] = Measure(1.787401575) scala> onecm * onecm res3: Measure[CMSQ] = Measure(1.0) scala> onecm * oneinch res4: Measure[CMSQ] = Measure(2.54) scala> oncem * Measure(1.0, LITER) console>:7: error: conformance mismatch scala> oneinch * 2 == twoinch res5: Boolean = true
Before you get too excited, I haven't implemented this, I just dummied up a REPL session. I'm not even sure of the syntax, I just want to be able to handle things like adding Measured quantities (even with mixed units), multiplying Measured quantities, and so on, and ideally, I like Scala's vaunted type-system to guarantee at compile-time that expressions make sense.
My questions:
- Is there extant terminology for this problem?
- Has this already been done in Scala?
- If not, how would I represent concepts like "length" and "length measured in meters"?
- Has this been done in some other language?
A $330-million Mars probe was lost because the contractor was using yards and pounds and NASA was using meters and newtons. A Measure library would have prevented the crash.
Answers
Well, this functionality exists in Java, meaning you can use it directly in Scala.
jsr-275, which was moved to google code. jscience implements the spec. Here's a good introduction. If you want a better interface, I'd use this as a base and build a wrapper around it.
F# has support for it, see for example this link for an introduction. There has been some work done in Scala on Units, for example here and here. There is a Scala compiler plugin as well, as described in this blog post. I briefly tried to install it, but using Scala 2.8.1, I got an exception when I started up the REPL, so I'm not sure whether this plugin is actively maintained at the moment.
Your question is fully answered with one word. You can thank me later.
FRINK. http://futureboy.us/frinkdocs/