WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Scala · Advanced · question 49 of 100

Discuss the concept of path-dependent types in more depth, including abstract type members and their use cases.?

📕 Buy this interview preparation book: 100 Scala questions & answers — PDF + EPUB for $5

Path-dependent types are an advanced feature of the Scala type system that allows you to express precisely how an object’s type depends on the object’s value. This can help represent complex relationships between objects and their types in a type-safe manner. In Scala, path-dependent types work in the context of nested classes and abstract type members.

### Nested classes

In Scala, you can define classes within other classes, called nested classes. The instances of the inner class are tied to the instances of the outer class.

Here’s a simple example of nested classes:

class Outer {
  class Inner
  def createInnerInstance(): Inner = new Inner
}

val outer1 = new Outer
val outer2 = new Outer
val inner1 = outer1.createInnerInstance()
val inner2 = outer2.createInnerInstance()

In this example, ‘inner1‘ is of type ‘outer1.Inner‘, and ‘inner2‘ is of type ‘outer2.Inner‘. These are different types, and they are considered path-dependent types because they depend on the values of ‘outer1‘ and ‘outer2‘.

### Abstract type members

Abstract type members are type members of a class or a trait that are not concrete types. The concrete types will be provided by a subtype or implementation.

Here’s a simple example:

trait Container {
  type T
  def items: List[T]
  def put(item: T): Unit
}

class StringContainer extends Container {
  type T = String
  private var _items = List.empty[String]
  def items = _items
  def put(item: String): Unit = {
    _items = item :: _items
  }
}

In this example, ‘Container‘ is a trait with an abstract type member ‘T‘. The ‘StringContainer‘ extends ‘Container‘ and provides a concrete type for ‘T‘, namely ‘String‘.

### Use cases for path-dependent types and abstract type members

A powerful use case for path-dependent types and abstract type members is representing complex relationships between objects in a type-safe manner.

Consider the following scenario:

trait Graph {
  type Node <: NodeLike
  trait NodeLike {
    def connectTo(node: Node): Unit
  }

  def nodes: List[Node]
  def newNode(): Node

  def connectAllNodes(): Unit = {
    for (node1 <- nodes; node2 <- nodes) node1.connectTo(node2)
  }
}

In this example, we have a ‘Graph‘ trait with an abstract type member ‘Node‘ and a nested trait ‘NodeLike‘. The ‘Node‘ class is defined to be a subtype of ‘NodeLike‘. This allows us to express the relationship that nodes within the same graph can only be connected to each other, and nodes belonging to different graphs cannot be connected. To illustrate this further, let’s create concrete implementations of the graph and node classes:

class SimpleGraph extends Graph {
  class SimpleNode extends NodeLike {
    private var connectedNodes: List[Node] = Nil
    def connectTo(node: Node): Unit = {
      connectedNodes = node :: connectedNodes
    }
  }

  private var _nodes: List[Node] = Nil
  def nodes = _nodes

  def newNode(): Node = {
    val node = new SimpleNode
    _nodes = node :: _nodes
    node
  }
}

Now, we can create and connect nodes within the same graph:

val graph1 = new SimpleGraph
val node1 = graph1.newNode()
val node2 = graph1.newNode()
node1.connectTo(node2) // This is allowed

However, attempting to connect nodes from different graphs will result in a type error:

val graph2 = new SimpleGraph
val node3 = graph2.newNode()
// The following line will result in a compile-time type error
// node1.connectTo(node3)

Through the use of path-dependent types and abstract type members, Scala allows us to create complex relationships between objects that can be enforced at the type level, resulting in cleaner and safer code.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Scala interview — then scores it.
📞 Practice Scala — free 15 min
📕 Buy this interview preparation book: 100 Scala questions & answers — PDF + EPUB for $5

All 100 Scala questions · All topics