Skip to content

Instantly share code, notes, and snippets.

@Centaur
Created October 21, 2015 15:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Centaur/8fe066c605d37aa5f6fe to your computer and use it in GitHub Desktop.
Save Centaur/8fe066c605d37aa5f6fe to your computer and use it in GitHub Desktop.
Nested Lens
import monocle.macros.Lenses
import language.higherKinds
@Lenses("_") case class Street(name: String)
@Lenses("_") case class Address(street: Street)
@Lenses("_") case class Company(addresses: Seq[Address])
@Lenses("_") case class Employee(company: Company)
object ILens {
val employee = Employee(Company(Seq(
Address(Street("aaa string")),
Address(Street("bbb string")),
Address(Street("bpp string")))))
import Employee._
import Company._
import Address._
import Street._
def main(args: Array[String]) {
def transformName(name: String) = if(name.startsWith("b")) name.toUpperCase else name
def singleAddr(address: Address) = (_street composeLens _name).modify(transformName)(address)
val converted = (_company composeLens _addresses).modify(_.map(singleAddr))(employee)
println(converted)
}
}
@Centaur
Copy link
Author

Centaur commented Oct 21, 2015

Version that need not modify Seq to List in case class definitions:

import monocle.Iso
import monocle.function.Each._
import monocle.macros.Lenses
import language.higherKinds

@Lenses("_") case class Street(name: String)
@Lenses("_") case class Address(street: Street)
@Lenses("_") case class Company(addresses: Seq[Address])
@Lenses("_") case class Employee(company: Company)

object ILens {
  val employee = Employee(Company(Seq(
    Address(Street("aaa string")),
    Address(Street("bbb string")),
    Address(Street("bpp string")))))

  import monocle.std.list._

  import Employee._
  import Company._
  import Address._
  import Street._

  def main(args: Array[String]) {
    def transformName(name: String) = if(name.startsWith("b")) name.toUpperCase else name
    val seq2List = Iso.apply[Seq[Address], List[Address]](_.toList)(_.toSeq)
    val converted = (_company   composeTraversal (_addresses composeIso seq2List composeTraversal each) composeLens _street composeLens _name).modify(transformName)(employee)
    println(converted)
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment