fork(1) download
  1. object Fuels {
  2.  
  3. trait Monoid[F] {
  4. def zero: F
  5. def append(f1: F, f2: F): F
  6. }
  7.  
  8. object Monoid {
  9. def fold[F](as: Seq[F])(implicit m: Monoid[F]): F = as.foldLeft(m.zero)(m.append)
  10. }
  11.  
  12. case class Fuel[F <: FuelType](amount: Double, fuelType: F = Petrol) {
  13. def +(that : Fuel[F]): Fuel[F] = {
  14. copy(amount = this.amount + that.amount)
  15. }
  16. }
  17.  
  18. def add[F <: FuelType](x: Fuel[F], y: Fuel[F]): Fuel[F] = x + y
  19.  
  20. sealed trait FuelType {
  21. val name : String
  22. }
  23. case object Petrol extends FuelType{
  24. override val name = "Petrol"
  25. }
  26. case object Diesel extends FuelType{
  27. override val name = "Diesel"
  28. }
  29. case object Hydrogen extends FuelType{
  30. override val name = "Hydrogen"
  31. }
  32.  
  33. implicit def fuelMonoid[F <:FuelType](implicit fuelType: F): Monoid[Fuel[F]] = new Monoid[Fuel[F]] {
  34. override def zero: Fuel[F] = Fuel(0, fuelType)
  35. override def append(m1: Fuel[F], m2: Fuel[F]): Fuel[F] = m1 + m2
  36. }
  37. }
  38.  
  39. object Main {
  40. def main (args: Array[String] ) {
  41. import Fuels._
  42. println(Fuel(10, Petrol) + Fuel(20, Petrol))
  43. println(add(Fuel(10, Petrol), Fuel(20, Petrol)))
  44. implicit val petrolM = fuelMonoid(Petrol)
  45. println(Monoid.fold(Seq(Fuel(10, Petrol), Fuel(20, Petrol), Fuel(30, Petrol))))
  46. }
  47. }
Success #stdin #stdout 0.39s 382080KB
stdin
Standard input is empty
stdout
Fuel(30.0,Petrol)
Fuel(30.0,Petrol)
Fuel(60.0,Petrol)