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) =&gt; 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?
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) =&gt; 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).