Skip to content

Instantly share code, notes, and snippets.

@soc
Created April 6, 2012 23:16
Show Gist options
  • Select an option

  • Save soc/2323881 to your computer and use it in GitHub Desktop.

Select an option

Save soc/2323881 to your computer and use it in GitHub Desktop.
package scalax.units
object Units {
import scalax.math.Numeric
import scalax.math.Numeric._
import Integers._
import Addables._
import Subtractables._
trait Unit {
type M <: MInt
type KG <: MInt
type S <: MInt
type A <: MInt
type K <: MInt
type Mol <: MInt
type CD <: MInt
}
final class TUnit[_M <: MInt, _KG <: MInt, _S <: MInt, _A <: MInt, _K <: MInt, _Mol <: MInt, _CD <: MInt] {
type M = _M
type KG = _KG
type S = _S
type A = _A
type K = _K
type Mol = _Mol
type CD = _CD
}
case class Quantity[M <: MInt, KG <: MInt, S <: MInt, A <: MInt, K <: MInt, Mol <: MInt, CD <: MInt, T: Numeric](value: T) {
import Quantity._
private val num = numeric[T]
def asInt = Quantity[M, KG, S, A, K, Mol, CD, Int](num.toType[Int](value))
def asLong = Quantity[M, KG, S, A, K, Mol, CD, Long](num.toType[Long](value))
def asFloat = Quantity[M, KG, S, A, K, Mol, CD, Float](numeric[T].toType[Float](value))
def asDouble = Quantity[M, KG, S, A, K, Mol, CD, Double](numeric[T].toType[Double](value))
def toInt: Int = (num.toType[Int](value))
def toLong: Long = (num.toType[Long](value))
def toFloat: Float = (num.toType[Float](value))
def toDouble: Double = (num.toType[Double](value))
type This = Quantity[M, KG, S, A, K, Mol, CD, T]
def +(m: This) = Quantity[M, KG, S, A, K, Mol, CD, T](num.plus(value, m.value))
def -(m: This) = Quantity[M, KG, S, A, K, Mol, CD, T](num.minus(value, m.value))
def *[M2 <: MInt, KG2 <: MInt, S2 <: MInt, A2 <: MInt, K2 <: MInt, Mol2 <: MInt, CD2 <: MInt](m: Quantity[M2, KG2, S2, A2, K2, Mol2, CD2, T]) = Quantity[M + M2, KG + KG2, S + S2, A + A2, K + K2, Mol + Mol2, CD + CD2, T](num.times(value, m.value))
def /[M2 <: MInt, KG2 <: MInt, S2 <: MInt, A2 <: MInt, K2 <: MInt, Mol2 <: MInt, CD2 <: MInt](m: Quantity[M2, KG2, S2, A2, K2, Mol2, CD2, T]) = Quantity[M - M2, KG - KG2, S - S2, A - A2, K - K2, Mol - Mol2, CD - CD2, T](num.div(value, m.value))
//////////////////////////////////////////////////////////////////////////////////////////////
override def toString = value + " " + implicitly[ToString[M, KG, S, A, K, Mol, CD]].toString
}
object Quantity {
trait ToString[M <: MInt, KG <: MInt, S <: MInt, A <: MInt, K <: MInt, Mol <: MInt, CD <: MInt]
implicit object Meter extends ToString[_1, _0, _0, _0, _0, _0, _0]{
override def toString = " m"
}
}
//////////////////////////////////////////////////////////////////////////////////////////////
/*
Units.scala:52: could not find implicit value for parameter e: scalax.units.Units.Quantity.ToString[M,KG,S,A,K,Mol,CD]
[error] override def toString = value + " " + implicitly[ToString[M, KG, S, A, K, Mol, CD]].toString
[error] ^
*/
implicit def measure[T: Numeric](v: T): Quantity[_0, _0, _0, _0, _0, _0, _0, T] = Quantity[_0, _0, _0, _0, _0, _0, _0, T](v)
implicit def numericToQuantity[T: Numeric](v: T): QuantityConstructor[T] = new QuantityConstructor[T](v)
class QuantityConstructor[T: Numeric](v: T) {
private val num = numeric[T]
def m = Quantity[_1, _0, _0, _0, _0, _0, _0, T](v)
def kg = Quantity[_0, _1, _0, _0, _0, _0, _0, T](v)
def s = Quantity[_0, _0, _1, _0, _0, _0, _0, T](v)
def a = Quantity[_0, _0, _0, _1, _0, _0, _0, T](v)
def k = Quantity[_0, _0, _0, _0, _1, _0, _0, T](v)
def mol = Quantity[_0, _0, _0, _0, _0, _1, _0, T](v)
def cd = Quantity[_0, _0, _0, _0, _0, _0, _1, T](v)
def minute = Quantity[_0, _0, _1, _0, _0, _0, _0, T](num.times(v, num.fromInt(60)))
def hour = Quantity[_0, _0, _1, _0, _0, _0, _0, T](num.times(v, num.fromInt(3600)))
}
type Length[T] = Quantity[_1, _0, _0, _0, _0, _0, _0, T]
type Mass[T] = Quantity[_0, _1, _0, _0, _0, _0, _0, T]
type Time[T] = Quantity[_0, _0, _1, _0, _0, _0, _0, T]
type Currency[T] = Quantity[_0, _0, _0, _1, _0, _0, _0, T]
type Temperature[T] = Quantity[_0, _0, _0, _0, _1, _0, _0, T]
type Mol[T] = Quantity[_0, _0, _0, _0, _0, _1, _0, T]
type LuminousIntensity[T] = Quantity[_0, _0, _0, _0, _0, _0, _1, T]
type Area[T] = Quantity[_2, _0, _0, _0, _0, _0, _0, T]
type Volume[T] = Quantity[_3, _0, _0, _0, _0, _0, _0, T]
type Speed[T] = Quantity[_1, _0, _1#Neg, _0, _0, _0, _0, T]
type Acceleration[T] = Quantity[_1, _0, _2#Neg, _0, _0, _0, _0, T]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment