Я ищу способ иметь классы, которые ведут себя как классы case, но это автоматически hash 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
}
}
И, например, while
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]
(или аналогичный). Может кто-нибудь придумать какую-то систему вуду, чтобы помочь мне, или мне придется ждать, когда будет доступен макроязык?