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

Scala · Expert · question 68 of 100

Discuss the use of lenses and prisms in Scala for working with immutable data structures.?

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

Lenses and prisms are functional programming patterns that help in working with deeply nested immutable data structures in a more elegant and convenient way. They both are part of a more general abstraction known as optics, which aim to generalize the idea of "zooming in" on a particular part of a data structure to perform some transformation.

In this answer, we will briefly discuss lenses, prisms, and their respective use-cases in Scala.

## Lenses

A lens is a functional programming construct that helps in "zooming in" on a particular field of a case class in Scala and compose those "zooming operations" to work with nested immutable data structures.

A lens can be thought of as a pair of getter and setter functions for a specific field in a case class. The main advantage of using lenses is that they can be composed to create complex data manipulation operations on deeply nested and immutable data structures.

For instance, consider the following case classes with nested fields:

case class Street(name: String, number: Int)
case class Address(city: String, street: Street)
case class Person(name: String, age: Int, address: Address)

Let’s say we want to update the street number of a ‘Person‘. Using lenses, we can do it in a more declarative style:

import monocle.Lens
import monocle.macros.GenLens

val streetNumberLens: Lens[Street, Int] = GenLens[Street](_.number)
val personStreetLens: Lens[Person, Street] = GenLens[Person](_.address.street)

val composedLens: Lens[Person, Int] = personStreetLens composeLens streetNumberLens

val person = Person("John Doe", 30, Address("New York", Street("Main St", 123)))

val newPerson = composedLens.modify(_ + 1)(person)

In the above example, we first import the necessary Monocle library components (a popular optics library in Scala). We then define lenses for accessing the fields of the case classes using the ‘GenLens‘ macro. Next, we compose the lenses to create a ‘Lens[Person, Int]‘ that can modify the street number. Finally, we apply the composed lens to update the street number of a person.

## Prisms

Prisms are another optic kind that is more suited to data structures with several possible representations, such as sealed trait hierarchies or ADTs (algebraic data types). Prisms help in zooming in on a particular variant of the sealed hierarchy, allowing us to access and modify their values if they match the target case. It can be thought of as a getter and optional setter.

Consider the following example:

sealed trait Shape
case class Circle(radius: Double) extends Shape
case class Rectangle(width: Double, height: Double) extends Shape

Using prisms, we can focus on a specific variant of ‘Shape‘ and access its properties:

import monocle.Prism
import monocle.macros.GenPrism

val shapeToCircle: Prism[Shape, Circle] = GenPrism[Shape, Circle]

val shape: Shape = Circle(5.0)

val circleWithBiggerRadius: Option[Shape] = shapeToCircle.modifyOption(_.copy(radius = 10.0))(shape)

In the above example, we first import the necessary components from Monocle. Then, we define a prism for accessing a ‘Circle‘ instance from a ‘Shape‘. When we use the ‘modifyOption‘ function on the defined prism, we can update the circle’s radius if it is indeed a ‘Circle‘. If not, the function will return ‘None‘.

## Conclusion

Lenses and prisms provide elegant and composable ways of working with immutable data structures in Scala. Lenses are well-suited for working with nested case classes, while prisms serve a similar purpose for sealed trait hierarchies or ADTs. Both lenses and prisms enable more declarative and functional programming style, allowing for more maintainable and readable 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