Skip to content

Instantly share code, notes, and snippets.

@noahlz
Last active August 29, 2015 14:02
Show Gist options
  • Save noahlz/9b8497746481f1247970 to your computer and use it in GitHub Desktop.
Save noahlz/9b8497746481f1247970 to your computer and use it in GitHub Desktop.
Learning about generic types that need to access their subtypes - in Scala
trait Color {
def name: String
}
abstract class PrimaryColor(val name: String) extends Color
case object Red extends PrimaryColor("Red")
case object Blue extends PrimaryColor("Blue")
case object Yellow extends PrimaryColor("Yellow")
trait HasColors {
def colors: collection.immutable.Set[Color]
}
/** http://twitter.github.io/scala_school/advanced-types.html#fbounded */
abstract class Paint[P <: Paint[P]] extends HasColors {
def name: String
def price: Double
def id: Int
def withColor(color: Color): Paint[P] = {
_colors += color
this
}
private val _colors = collection.mutable.Set.empty[Color]
def colors = _colors.toSet
def lineItem: String = s"[${id}] ${name}${colors.mkString("(",",",")")}: $$${price}"
}
case class OilPaints(id: Int, price: Double) extends Paint[OilPaints] {
val name = "Oils"
}
case class WaterColors(id: Int, price: Double) extends Paint[WaterColors] {
val name = "WaterColors"
}
object Main extends App {
println("******************")
val oil = OilPaints(100, 1.0).withColor(Red).withColor(Blue)
val wc = WaterColors(200, 2.0).withColor(Yellow)
println(oil.lineItem)
println(wc.lineItem)
//val broken: WaterColor = OilPaint(3.0).withColor(Red)
println("******************")
val p: Paint[_] = WaterColors(300, 4.0)
println(p.lineItem)
println("******************")
println("Printing list:")
val paints = OilPaints(400, 1.0) ::
WaterColors(500, 2.0).withColor(Yellow) ::
OilPaints(600, 3.0).withColor(Red) ::
OilPaints(700, 4.0).withColor(Yellow).withColor(Blue) :: Nil
paints.foreach(p => println(p.lineItem))
}
// OUTPUT:
// ******************
// [100] Oils(Red,Blue): $1.0
// [200] WaterColors(Yellow): $2.0
// ******************
// [300] WaterColors(): $4.0
// ******************
// Printing list:
// [400] Oils(): $1.0
// [500] WaterColors(Yellow): $2.0
// [600] Oils(Red): $3.0
// [700] Oils(Blue,Yellow): $4.0
@noahlz
Copy link
Author

noahlz commented Jun 17, 2014

scala> val b = OilPaints(100, 1) :: WaterColors(200, 2.0) :: Nil
b: List[org.example.Paint[_ >: org.example.WaterColors with org.example.OilPaints <: org.example.Paint[_ >: org.example.WaterColors with org.example.OilPaints <: Product with Serializable with org.example.HasColors] with Product with Serializable] with Product with Serializable] = List(OilPaints(100,1.0), WaterColors(200,2.0))

Gah!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment