# Aggregating values of a path-dependent type

I have a type representing an immutable order which contains immutable order lines that belong to it. I want to use path-dependent types for this. Obviously you cannot instantiate a path-dependent type without having the value it depends on, so I decided to take a function from the constructor. Since (order: Order) => Seq[order.OrderLine] is impossible, I use a simple structural type.

final class Order private() {
case class OrderLine(x: Int, y: Double) { }

def this(makeOrderLines: { def apply(order: Order): Seq[order.OrderLine] }) = {
this()
_orderLines = makeOrderLines(this)
}

private var _orderLines: Seq[OrderLine] = null
def orderLines = _orderLines
}

object Main extends App {
val order = new Order(new {
def apply(order: Order) =
Seq(order.OrderLine(1, 1.0), order.OrderLine(2, 2.0))
})
println(order.orderLines)
}


I find this approach very ugly. Especially not being able to use a lambda expression irks me (the lambda expression would return Seq[Order#OrderLine] instead of Seq[order.OrderLine] since it has be of type Function1[_, _] where path-dependent types are not possible).

Is there a better way of doing this?

• I'm not sure why you absolutely want to use path-dependent types. Wouldn't defining OrderLine in a companion object Order be clean enough? It would be a more common approach. – toto2 Jul 25 '14 at 1:57

Taking a shower can do wonders. :)

You can take tuples instead and convert those to this.OrderLines in the constructor.

final class Order private() {
case class OrderLine(x: Int, y: Double) { }

def this(rawOrderLines: Seq[(Int, Double)]) = {
this()
_orderLines = rawOrderLines.map { case (x, y) => OrderLine(x, y) }
}

private var _orderLines: Seq[OrderLine] = null
def orderLines = _orderLines
}

object Main extends App {
val order = new Order(Seq((1, 1.0), (2, 2.0)))
println(order.orderLines)
}


It’s simpler and more concise, although the call-site may still be rather confusing (not that it wasn’t already).