Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat is the correct way to specify type variance for methods in a companion object
    primarykey
    data
    text
    <p>For me one of the more confusing aspects of the Scala type system is understanding covariance, contravariance, type bounds etc. </p> <p>I am trying to create a generic <code>Repository</code> trait that can be extended by companion objects objects of classes that extend a <code>Page</code> trait. The idea is that the companion object will be responsible for creating new instances etc. These page instances will need to be cleaned up if they haven't been accessed within some period of time. Thus the base <code>Repository</code> trait will register them in a list of repositories that can be checked in a background actor thread.</p> <p>Below is a stripped down version of the code. I'm getting a <code>type mismatch</code> error on the call to <code>register(pages)</code>. The compiler found <code>HashMap[String, T]</code> but is expecting <code>HashMap[String, Page]</code>. I can't figure out what to do to make the compiler happy. I can define the register method as <code>def register[T &lt;: Page](repo: HashMap[String, T) ...</code> but that just defers the problem to the reference of the <code>var repos</code> which I cannot qualify generically. I would appreciate it if someone could demonstrate the correct way to specify the types.</p> <p><strong>EDIT</strong> I can get it to work if I declare the hashmap as <code>HashMap[String, Page]</code> and then cast the <code>page</code> value retrieved from the hashmap with <code>page.asInstanceOf[String, T]</code>. Is there a way to avoid the cast?</p> <pre><code>trait Page { val id = Random.hex(8) private var lastAccessed = new Date ... } object Page { import scala.collection.mutable.HashMap trait Repository[T &lt;: Page] { private val pages = new HashMap[String, T] register(pages) def newPage: T def apply(): T = { val page = newPage pages(page.id) = page page } def apply(id: String): T = { pages.get(id) match { case Some(page) =&gt; page.lastAccessed = now page case None =&gt; this() } } ... } private var repos: List[HashMap[String, Page]] = Nil private def register(repo: HashMap[String, Page]) { repos = repo :: repos } ... } class CoolPage extends Page object CoolPage extends Page.Repository[CoolPage] { def newPage = new CoolPage } val p = CoolPage() </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload