ZIO Optics is a library that makes it easy to modify parts of larger data structures based on a single representation of an optic as a combination of a getter and setter.
When we are working with immutable nested data structures, updating and reading operations could be tedious with lots of boilerplates. Optics is a functional programming construct that makes these operations more clear and readable.
Key features of ZIO Optics:
- Unified Optic Data Type — All the data types like
Optional, and so forth are type aliases for the core
- Composability — We can compose optics to create more advanced ones.
- Embracing the Tremendous Power of Concretion — Using concretion instead of unnecessary abstractions, makes the API more ergonomic and easy to use.
- Integration with ZIO Data Types — It supports effectful and transactional optics that works with ZIO data structures like
- Helpful Error Channel — Like ZIO, the
Opticsdata type has error channels to include failure details.
In order to use this library, we need to add the following line in our
libraryDependencies += "dev.zio" %% "zio-optics" % "0.1.0"
In this example, we are going to update a nested data structure using ZIO Optics:
case class Developer(name: String, manager: Manager)
case class Manager(name: String, rating: Rating)
case class Rating(upvotes: Int, downvotes: Int)
val developerLens = Lens[Developer, Manager](
get = developer => Right(developer.manager),
set = manager => developer => Right(developer.copy(manager = manager))
val managerLens = Lens[Manager, Rating](
get = manager => Right(manager.rating),
set = rating => manager => Right(manager.copy(rating = rating))
val ratingLens = Lens[Rating, Int](
get = rating => Right(rating.upvotes),
set = upvotes => rating => Right(rating.copy(upvotes = upvotes))
// Composing lenses
val optic = developerLens >>> managerLens >>> ratingLens
val jane = Developer("Jane", Manager("Steve", Rating(0, 0)))
val updated = optic.update(jane)(_ + 1)
- Zymposium - Optics by Adam Fraser and Kit Langton (June 2021) — Optics are great tools for working with parts of larger data structures and come up in disguise in many places such as ZIO Test assertions.