Tuesday, 2 July 2013

Scala code snippet: strong typed graph nodes

In the post Scala Lazy Types, I explored the use of abstract types for nodes in a graph. In this post, I will create another version of a node with stronger type constraints on both the parent nodes and the children nodes.
Using the typical DAG for pricing graphs, with Futures, Bonds, Cheapest-To-Deliver and Benchmarks.
This version uses the concept of generalised typed constraints, which is used in the implicit argument to the methods addParent (+^) and addChild (+!).
trait STNode {
  type ParentNodeType <: STNode
  type ChildNodeType <: STNode
    
  var parents: List[ParentNodeType] = List()
  var children: List[ChildNodeType] = List()
    
  def +^ (parent: ParentNodeType)(implicit thisAsChild : this.type <:< parent.ChildNodeType) = {
    parents ::= parent
    parent.children ::= thisAsChild(this)
  }
    
  def +! (child: ChildNodeType)(implicit thisAsParent : this.type <:< child.ParentNodeType) {
    children ::= child
    child.parents ::= thisAsParent(this)
  }
}
Let's now define the abstract bonds and futures pricing nodes:
trait Bond extends STNode {
  override type ChildNodeType = Bond
}

trait Future extends STNode {
  override type ParentNodeType = Nothing
  override type ChildNodeType = Bond
}
Then the real implementations: a Market Future, a Manual Future, a Cheapest-To-Deliver Bond, a Gross-Basis Bond, and a Benchmark Bond:
class FutureMarket extends Future
class FutureManual extends Future
  
class BondGrossBasis extends Bond {
  override type ParentNodeType = Future
}
class BondCheapestToDeliver extends Bond {
  override type ParentNodeType = Future
}
class BondBenchmark extends Bond {
  override type ParentNodeType = Bond
  override type ChildNodeType = Bond
}
And finally some tests:
val future = new FutureMarket
val ctd = new BondCheapestToDeliver
val bench = new BondBenchmark

future +! ctd
bench +^ ctd
Obviously, the following does not compile if you try to add a future as a child to a bond:
bench +! future
with type mismatch; found : investigations.StrongTypedGraph.FutureMarket required: bench.ChildNodeType

1 comment:

Hemant said...

Nice one! Hemant

Blog Archive