fork(1) download
  1. trait CanQuantify[Q <: Quantity[T], T] {
  2. def apply(value: T): Q
  3. }
  4.  
  5. trait Quantity[T] {
  6. type Self <: Quantity[T]
  7.  
  8. def value: T
  9.  
  10. def +(that: Quantity[T])(implicit q: CanQuantify[Self, T], num: Numeric[T]) = {
  11. import num._
  12. q(value + that.value)
  13. }
  14.  
  15. def *[R <: Quantity[T]](that: R)(implicit num: Numeric[T]) = {
  16. import num._
  17. Times[T, Self, R](value * that.value)
  18. }
  19.  
  20. def /[R <: Quantity[T]](that: R)(implicit num: Fractional[T]) = {
  21. import num._
  22. Per[T, Self, R](value / that.value)
  23. }
  24. }
  25.  
  26. case class Times[T, Q <: Quantity[T], R <: Quantity[T]](value: T) extends Quantity[T] {
  27. override type Self = Per[T, Q, R]
  28.  
  29. def /(that: R)(implicit q: CanQuantify[Q, T], num: Fractional[T]) = {
  30. import num._
  31. q(value / that.value)
  32. }
  33. }
  34.  
  35. case class Per[T, Q <: Quantity[T], R <: Quantity[T]](value: T) extends Quantity[T] {
  36. override type Self = Per[T, Q, R]
  37.  
  38. def *(that: R)(implicit q: CanQuantify[Q, T], num: Numeric[T]) = {
  39. import num._
  40. q(value * that.value)
  41. }
  42. }
  43.  
  44. case class ProductCount(value: Double) extends Quantity[Double] {
  45. override type Self = ProductCount
  46. }
  47.  
  48. case class BoxCount(value: Double) extends Quantity[Double] {
  49. override type Self = BoxCount
  50. }
  51.  
  52. object canQuantifies {
  53. implicit val productCountCanQuantify = new CanQuantify[ProductCount, Double] {
  54. override def apply(value: Double) = ProductCount(value)
  55. }
  56.  
  57. implicit val boxCountCanQuantify = new CanQuantify[BoxCount, Double] {
  58. override def apply(value: Double) = BoxCount(value)
  59. }
  60. }
  61. import canQuantifies._
  62.  
  63. object Main extends App {
  64. val products = ProductCount(10.0)
  65. val boxes = BoxCount(5.0)
  66. var n = products / boxes
  67. n = n * boxes / boxes
  68. }
Success #stdin #stdout 0.24s 381696KB
stdin
Standard input is empty
stdout
Standard output is empty