Richard Searle

home

Adding typing to Monitor

05 Feb 2012

The phantom type idiom can help to solve the difficulty of distinguishes Monitors that wrap the same type. Type erasure unfortunately limits its usefulness. A bettter approach is to create a case class for each type, using inheritance to provide the boilerplate.
abstract class BaseMonitor[T, S](implicit p: S => T) {
  def s: S
  private val v = p(s)
  def apply[R](f: T => R) = synchronized { f(v) }
}
Example
    implicit def toDom(s: String): Document = (DocumentBuilderFactory.newInstance().newDocumentBuilder()).parse(new InputSource(new StringReader(s)))

    case class XA(s: String) extends BaseMonitor[org.w3c.dom.Document, String]

    val mdoc = XA("value")
    mdoc { _.getDocumentElement.getTextContent } must beEqualTo("value")
Note that the only field in the case class must be named s to match the abstract method in BaseMonitor. The common BaseMonitor type structure can be extracted as follows
 type XML = BaseMonitor[org.w3c.dom.Document, String]
 case class XA(s: String) extends XML
 case class XB(s: String) extends XML