|
View:
New views
7 Messages
—
Rating Filter:
Alert me
|
|
|
[scala] What is the equivalent of this program using type parameters?Problem statement:
- Allow addition of KG + Gram, Meter + Kilometer but prevent addition of Meter and Miles - Allow conversion from Meter to Miles, KG to pounds but prevent conversion from Miles to Grams
- Allow multiplication of any two units (return type Double) I came up with the following program using abstract type members, but still struggling to find solution using type parameters/generics. Will appreciate any help/guidance. Thanks.
trait AbstractMeasure { type Quantity <: AbstractQuantity trait AbstractQuantity { this: Quantity =>
type Unit <: AbstractUnit trait AbstractUnit { val amount: Double implicit val implicitThis = this def +(that: Unit) = make(amount + that.to[this.type].amount)
def *(that: AbstractMeasure#AbstractQuantity#AbstractUnit) = amount * that.amount def *(that: Double) = make(amount * that)
def to[T<: Quantity#AbstractUnit](implicit m: Manifest[T]) = { val mappedUnit = convert(make(1)).find(_.getClass == m.erasure).get
mappedUnit * amount } }
} } object Singleton { type U = AbstractMeasure#AbstractQuantity#AbstractUnit def convert: Map[U,List[U]] = Map( Meter(1) -> List(Meter(1), KM(0.001) , Mile(0.00062), Yard(1.093)), KM(1) -> List(Meter(1000), KM(1) , Mile(0.62), Yard(1093)),
Mile(1) -> List(Meter(1609), KM(1.069) , Mile(1), Yard(1760)), ....
) def make(x: Double)(implicit o: U): U = o match { case Meter(_) => Meter(x) case KM(_) => KM(x)
case Mile(_) => Mile(x) ... } } object Length extends AbstractMeasure {
type Quantity = LengthQuantity trait LengthQuantity extends AbstractQuantity object Metric extends LengthQuantity { type Unit = LengthUnit trait LengthUnit extends AbstractUnit case class Meter(amount: Double) extends LengthUnit case class KM(amount: Double) extends LengthUnit
} object English extends LengthQuantity { type Unit = LengthUnit abstract class LengthUnit extends AbstractUnit case class Mile(amount: Double) extends LengthUnit
case class Yard(amount: Double) extends LengthUnit } } object Weight extends AbstractMeasure { type Quantity = WeightQuantity trait WeightQuantity extends AbstractQuantity
object Metric extends WeightQuantity { type Unit = WeightUnit trait WeightUnit extends AbstractUnit case class Gram(amount: Double) extends WeightUnit
case class KG(amount: Double) extends WeightUnit } object English extends WeightQuantity { type Unit = WeightUnit trait WeightUnit extends AbstractUnit
case class Pound(amount: Double) extends WeightUnit case class Ounce(amount: Double) extends WeightUnit } } import Length.Metric._, Length.English._, Weight.Metric._, Weight.English._
println(KM(4) + Meter(5)) => KM(4.005) println(KM(5) + Mile(3)) //compile time error println(KM(5).to[Yard]) => Yard(5465.0) println(KG(2).to[Mile]) //compile time error
println(Meter(3) * Gram(9)) => 27 |
|
|
Re: [scala] What is the equivalent of this program using type parameters?Ahmed,
your example sounds similar to the Mars Climate Orbiter one which is the stereotypical example to make use of type members in the first place why do you want a solution using type parameters? I'm not sure you'll find one that is more elegant than one using type members Luc On Fri, Oct 16, 2009 at 2:38 PM, Mushtaq Ahmed <mushtaq.a@...> wrote: Problem statement: -- __~O -\ <, (*)/ (*) reality goes far beyond imagination |
|
|
[scala] Re: What is the equivalent of this program using type parameters?Mushtaq Ahmed wrote:
> Problem statement: > - Allow addition of KG + Gram, Meter + Kilometer but prevent addition of > Meter and Miles > - Allow conversion from Meter to Miles, KG to pounds but prevent > conversion from Miles to Grams > - Allow multiplication of any two units (return type Double) > > I came up with the following program using abstract type members, but > still struggling to find solution using type parameters/generics. Will > appreciate any help/guidance. Thanks. See: http://svn.assembla.com/svn/metascala/src/metascala/Units.scala /Jesper Nordenberg |
|
|
Re: [scala] What is the equivalent of this program using type parameters?why do you want a solution using type parameters? I always found parameterized types (especially with variance annotations) difficult to apply. This is an attempt to translate a known solution to a familiar problem... in the hope that the process will make these concepts easier to understand, maybe.
|
|
|
Re: [scala] Re: What is the equivalent of this program using type parameters?
Thanks for the pointer, Jesper. It seems too challenging for my abilities. Will keep it as a reference to gain some wisdom.
|
|
|
Re: [scala] Re: What is the equivalent of this program using type parameters?On Fri, Oct 16, 2009 at 10:42:14PM +0530, Mushtaq Ahmed wrote:
> See: > http://svn.assembla.com/svn/metascala/src/metascala/Units.scala > /Jesper Nordenberg > > Thanks for the pointer, Jesper. It seems too challenging for my > abilities. Will keep it as a reference to gain some wisdom. See <http://jim-mcbeath.blogspot.com/2008/11/practical-church-numerals-in-scala.html>, for a slightly simpler example with detailed explanation. By the way, Jesper, I believe your definition of / in Units.scala needs a / not * near the end of the line. -- Jim |
|
|
[scala] Re: What is the equivalent of this program using type parameters?Jim McBeath wrote:
> By the way, Jesper, I believe your definition of / in Units.scala > needs a / not * near the end of the line. Good catch :) /Jesper Nordenberg |
| Free embeddable forum powered by Nabble | Forum Help |