Mike Slinn

Connoisseur of Technology

Scala Existential Types and Salat

2012-08-06 / All Blog posts

For Scala programmers, the term 'existential types' does not refer to philosophers, or even authentic people. Ironically, most of the discussions of Scala's existential types that I found are be too abstract to be useful to me. I learn by doing; rarely do I learn from reading an abstract treatise. I guess this means that I could be labelled an existentialist.

Section 31.3 of Programming in Scala has some good information on Scala's existential types. Existential types is an abstraction of Java types, and abstraction is the antithesis of existentialism... aaaanyway, here is a sentence I stole from the book:
Iterator[_] means the same thing as Iterator[T] forSome { type T }

forSome is the keyword which tells the compiler that an existential type is being defined. This becomes useful if upper and/or lower bounds are used to define the type. For example, you can use a lower bound to specify that the type must be a subclass of PubSubAction with the following existential type:

T forSome { type T <: PubSubAction }

That is a lot of characters to type, so let's give this type a name:

type PubSubActionSubclass = T forSome { type T <: PubSubAction }

We can also define a type to help us with SalatDAO:

type SalatObject = T forSome { type T <: AnyRef }

Now lets use SalatObject as the parametric type for an invocation of Manifest.classType():

val mot = Manifest.classType[SalatObject](msg.getClass)

This is useful because the manifest can be passed to a SalatDAO constructor, which will create a DAO object for whatever type is supplied. In the following code, PubSubActionClass is just used to guarantee that the msg parameter is of the correct type; SalatDAO's constructor is defined to accept all subclasses of AnyRef.

import com.novus.salat.global.ctx

abstract class PubSubAction

object PubSubAction {
  def makeDAO[PubSubActionSubclass](msg: PubSubActionSubclass)
                              (implicit coll: MongoCollection) = {
    val mot = Manifest.classType[SalatObject](msg.getClass)
    val mid = Manifest.classType[Int](classOf[Int])
    new SalatDAO(coll)(mot, mid, ctx){}
  }
}

Now you know that you do not have to hard-code the creation of a DAO for every PubSubAction subclass. You can examine the source code for SalatDAO if you would like to learn more.

Assuming that psaMsg is an instance of a PubSubActionSubclass, you could call insert() as follows to do a generic insert. Because Salat has multiple methods called insert(), there is not enough type information for Scala to disambiguate the method reference unless the returned value from the single insert is stored in a variable, and that variable's type is provided:

val ignoredIndex: Option[Int] = makeDAO.insert(psaMsg)

There is only one variant of insert() which accepts a collection, so the reference is not ambiguous and the return value can be ignored:

dao.insert(Seq(psaMsg, psaMsg2, psaMsg3), WriteConcern.Normal)

Contact Mike Slinn

Unless you are a recruiter, in which case you should not try to make contact!

  • Email
  • Direct: 514-418-0156
  • Mobile: 650-678-2285

Disclaimer

The content on this web site is provided for general information purposes only and does not constitute legal or other professional advice or an opinion of any kind. Users of this web site are advised to seek specific legal advice by contacting their own legal counsel regarding any specific legal issues. Michael Slinn does not warrant or guarantee the quality, accuracy or completeness of any information on this web site. The articles published on this web site are current as of their original date of publication, but should not be relied upon as accurate, timely or fit for any particular purpose.

Accessing or using this web site does not create a client relationship. Although your use of the web site may facilitate access to or communications with Michael Slinn via e-mail or otherwise via the web site, receipt of any such communications or transmissions does not create a client relationship. Michael Slinn does not guarantee the security or confidentiality of any communications made by e-mail or otherwise through this web site.

This web site may contain links to third party web sites. Monitoring the vast information disseminated and accessible through those links is beyond Michael Slinn's resources and he does not attempt to do so. Links are provided for convenience only and Michael Slinn does not endorse the information contained in linked web sites nor guarantee its accuracy, timeliness or fitness for a particular purpose.


comments powered by Disqus

© 1976-2020, Michael Slinn. All rights reserved.