Я ищу способ иметь классы, которые ведут себя так же, как классы case, но автоматически хэш consed .
Один из способов добиться этого для целочисленных списков:
import scala.collection.mutable.{Map=>MutableMap}
sealed abstract class List
class Cons(val head: Int, val tail: List) extends List
case object Nil extends List
object Cons {
val cache : MutableMap[(Int,List),Cons] = MutableMap.empty
def apply(head : Int, tail : List) = cache.getOrElse((head,tail), {
val newCons = new Cons(head, tail)
cache((head,tail)) = newCons
newCons
})
def unapply(lst : List) : Option[(Int,List)] = {
if (lst != null && lst.isInstanceOf[Cons]) {
val asCons = lst.asInstanceOf[Cons]
Some((asCons.head, asCons.tail))
} else None
}
}
И, например, пока
scala> (5 :: 4 :: scala.Nil) eq (5 :: 4 :: scala.Nil)
resN: Boolean = false
мы получаем
scala> Cons(5, Cons(4, Nil)) eq Cons(5, Cons(4, Nil))
resN: Boolean = true
Теперь я ищу общий способ достижения это (или что-то очень похожее). В идеале я не хочу набирать больше, чем:
class Cons(val head : Int, val tail : List) extends List with HashConsed2[Int,List]
(или подобное). Может ли кто-нибудь придумать что-нибудь вроде системного вуду, чтобы мне помочь, или мне придется подождать, пока станет доступен макроязык?