Skip to content

Instantly share code, notes, and snippets.

@dadhi
Last active February 23, 2022 13:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dadhi/0350dae236b40eb72f4278dcfe948ec5 to your computer and use it in GitHub Desktop.
Save dadhi/0350dae236b40eb72f4278dcfe948ec5 to your computer and use it in GitHub Desktop.
Specialized factory type class in Scala
//live: https://scastie.scala-lang.org/dadhi/G2uzgCqXSbiav34bM602iw/68
trait EntryFactory[K] {
def create(key: K): Entry[K]
}
object EntryFactory {
implicit def anyFactory[K]: EntryFactory[K] =
new EntryFactory[K] {
override def create(key: K) = KEntry(key, key.hashCode)
}
implicit object IntFactory extends EntryFactory[Int] {
override def create(key: Int) = IntEntry(key)
}
def create[K: EntryFactory](key: K): Entry[K] =
implicitly[EntryFactory[K]].create(key)
}
trait SMap[@specialized(Int) K] {
def updated(key: K): SMap[K] = EntryFactory.create(key)
def +(key: K): SMap[K] = updated(key)
}
object SMap {
private case object Empty extends SMap[Nothing]
def empty[K]: SMap[K] = Empty.asInstanceOf[SMap[K]]
}
abstract class Entry[K] extends SMap[K]
case class KEntry[K](key: K, keyHash: Int) extends Entry[K]
case class IntEntry(key: Int) extends Entry[Int]
val e1 = EntryFactory.create("Hey")
val e2 = EntryFactory.create(42)
println(e1.toString + ": " + e1.getClass.getName + ";" + e2.toString + ": " + e2.getClass.getName)
val m = SMap.empty[Int] + 35 // WTF???? Why is it KEntry?
println(m.toString + ": " + m.getClass.getName)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment