Skip to content

Instantly share code, notes, and snippets.

@sshark
Last active August 29, 2015 14:26
Show Gist options
  • Select an option

  • Save sshark/22fa4092a73b64916248 to your computer and use it in GitHub Desktop.

Select an option

Save sshark/22fa4092a73b64916248 to your computer and use it in GitHub Desktop.
Using temperatures Celcius, Fahrenheit and Kelvin as an AnyVal example
/**
* To be a valid value class, the following rules must be followed (taken from Programming Scala 2nd Ed.):
* 1. The value class has one and only one public val argument (as of Scala 2.11,
* the argument can also be nonpublic).
* 2. The type of the argument must not be a value class itself.
* 3. If the value class is parameterized, the @specialized annotation can’t be used.
* 4. The value class doesn’t define secondary constructors.
* 5. The value class defines only methods, but no other vals and no vars.
* 6. However, the value class can’t override equals and hashCode.
* 7. The value class defines no nested traits, classes, or objects.
* 8. The value class cannot be subclassed.
* 9. The value class can only inherit from universal traits. An universal trait extends from Any.
* 10. The value class must be a top-level type or a member of an object that can be referenced
*/
trait Temperature extends Any {
def toKelvin: Kelvin
def toCelcius: Celcius
def toFahrenheit: Fahrenheit
}
class Kelvin(val t: Double) extends AnyVal with Temperature {
override def toKelvin = new Kelvin(t)
override def toCelcius = new Celcius(t - 273.15d)
override def toFahrenheit = new Fahrenheit((t - 273.15d) * 1.8 + 32.0)
}
class Fahrenheit(val t: Double) extends AnyVal with Temperature {
override def toKelvin = new Kelvin((t + 459.67) * 5/9)
override def toCelcius = new Celcius((t - 32) / 1.8)
override def toFahrenheit = new Fahrenheit(t)
}
class Celcius(val t: Double) extends AnyVal with Temperature {
override def toKelvin = new Kelvin(t + 273.15)
override def toCelcius = new Celcius(t)
override def toFahrenheit = new Fahrenheit(t * 1.8 + 32.0)
}
class TemperatureReporter(t: Temperature) {
override def toString = "[" + t.toKelvin.t + "K, " + t.toFahrenheit.t + "F, " +
t.toCelcius.t + "C]"
}
Seq(new Celcius(100), new Fahrenheit(212), new Kelvin(373.15)).foreach(
t => println(new TemperatureReporter(t)))
Seq(new Celcius(0), new Fahrenheit(32), new Kelvin(273.15)).foreach(
t => println(new TemperatureReporter(t)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment