Introduction
Immutability Pain.
val moveHarmeet = harmeet.copy( company = harmeet.company.copy( address = harmeet.company.address.copy( city = harmeet.company.address.city.copy( country = harmeet.company.address.city.country.copy( name = "Canada", code = "CA" ) ) ) ) )
Within complex objects, it is difficult to change inner properties. With Lens, we will see how to use our classes if we want to modify some of their properties.
Agenda
- Implement Lens using Scalaz.
- Implement Lens using Monocle.
Code: By Scalaz.
package WithLensPatternV1 {
import scalaz.Lens
case class Country(code: String, name: String)
case class City(name: String, country: Country)
case class Address(number: String, street: String, city: City)
case class Company(name: String, address: Address)
case class User(name: String, company: Company, address: Address)
object WithLensPatternV1 extends App {
val uk = Country("United Kingdom", "UK")
val london = City("London", uk)
val buckinghamPalace = Address("1", "Buckingham Place Road", london)
val company = Company("Knoldus", buckinghamPalace)
val canada = Country("Canada", "CA")
val toronto = City("Toronto", canada)
val mcMurray = Address("2", "610 McMurray Rd", toronto)
val harmeet = User("Harmeet Singh", company, mcMurray)
println("************ Before Move ************")
println(harmeet)
println("************ Move to Canada ************")
val userCompany = Lens.lensu[User, Company](
(u, company) => u.copy(company = company), _.company
)
val userAddress = Lens.lensu[User, Address](
(u, address) => u.copy(address = address), _.address
)
val companyAddress = Lens.lensu[Company, Address](
(c, address) => c.copy(address = address), _.address
)
val addressCity = Lens.lensu[Address, City](
(a, city) => a.copy(city = city), _.city
)
val cityCountry = Lens.lensu[City, Country](
(c, country) => c.copy(country = country), _.country
)
val countryName = Lens.lensu[Country, String](
(c, name) => c.copy(name = name), _.name
)
val countryCode = Lens.lensu[Country, String](
(c, code) => c.copy(code = code), _.code
)
val userCompanyCountryCode = userCompany >=> companyAddress >=> addressCity >=> cityCountry >=> countryCode
val userCompanyCountryName = userCompany >=> companyAddress >=> addressCity >=> cityCountry >=> countryName
val moveHarmeetCode = userCompanyCountryCode.set(harmeet, "CA")
val moveHarmeetName = userCompanyCountryName.set(moveHarmeetCode, "Canada")
println(moveHarmeetName)
}
}
package WithLensPatternV1 { import scalaz.Lens case class Country(code: String, name: String) case class City(name: String, country: Country) case class Address(number: String, street: String, city: City) case class Company(name: String, address: Address) case class User(name: String, company: Company, address: Address) object WithLensPatternV1 extends App { val uk = Country("United Kingdom", "UK") val london = City("London", uk) val buckinghamPalace = Address("1", "Buckingham Place Road", london) val company = Company("Knoldus", buckinghamPalace) val canada = Country("Canada", "CA") val toronto = City("Toronto", canada) val mcMurray = Address("2", "610 McMurray Rd", toronto) val harmeet = User("Harmeet Singh", company, mcMurray) println("************ Before Move ************") println(harmeet) println("************ Move to Canada ************") val userCompany = Lens.lensu[User, Company]( (u, company) => u.copy(company = company), _.company ) val userAddress = Lens.lensu[User, Address]( (u, address) => u.copy(address = address), _.address ) val companyAddress = Lens.lensu[Company, Address]( (c, address) => c.copy(address = address), _.address ) val addressCity = Lens.lensu[Address, City]( (a, city) => a.copy(city = city), _.city ) val cityCountry = Lens.lensu[City, Country]( (c, country) => c.copy(country = country), _.country ) val countryName = Lens.lensu[Country, String]( (c, name) => c.copy(name = name), _.name ) val countryCode = Lens.lensu[Country, String]( (c, code) => c.copy(code = code), _.code ) val userCompanyCountryCode = userCompany >=> companyAddress >=> addressCity >=> cityCountry >=> countryCode val userCompanyCountryName = userCompany >=> companyAddress >=> addressCity >=> cityCountry >=> countryName val moveHarmeetCode = userCompanyCountryCode.set(harmeet, "CA") val moveHarmeetName = userCompanyCountryName.set(moveHarmeetCode, "Canada") println(moveHarmeetName) } }
Code: By Monocle.
package WithLensPatternV2 {
import monocle.Lens
import monocle.macros.GenLens
case class Country(code: String, name: String)
case class City(name: String, country: Country)
case class Address(number: String, street: String, city: City)
case class Company(name: String, address: Address)
case class User(name: String, company: Company, address: Address)
object WithLensPatternV2 extends App {
val uk = Country("United Kingdom", "UK")
val london = City("London", uk)
val buckinghamPalace = Address("1", "Buckingham Place Road", london)
val company = Company("Knoldus", buckinghamPalace)
val canada = Country("Canada", "CA")
val toronto = City("Toronto", canada)
val mcMurray = Address("2", "610 McMurray Rd", toronto)
val harmeet = User("Harmeet Singh", company, mcMurray)
println("************ Before Move ************")
println(harmeet)
println("************ Move to Canada ************")
val userCompany: Lens[User, Company] = GenLens[User](_.company)
val userAddress = GenLens[User](_.address)
val companyAddress = GenLens[Company](_.address)
val addressCity = GenLens[Address](_.city)
val cityCountry = GenLens[City](_.country)
val countryCode = GenLens[Country](_.code)
val countryName = GenLens[Country](_.name)
val userCompanyCountryCode = userCompany composeLens companyAddress composeLens addressCity composeLens cityCountry composeLens countryCode
val userCompanyCountryName = userCompany composeLens companyAddress composeLens addressCity composeLens cityCountry composeLens countryName
val moveHarmeetCode = userCompanyCountryCode.set("CA")(harmeet)
val moveHarmeetName = userCompanyCountryName.set("Canada")(moveHarmeetCode)
println(moveHarmeetName)
}
}
package WithLensPatternV2 { import monocle.Lens import monocle.macros.GenLens case class Country(code: String, name: String) case class City(name: String, country: Country) case class Address(number: String, street: String, city: City) case class Company(name: String, address: Address) case class User(name: String, company: Company, address: Address) object WithLensPatternV2 extends App { val uk = Country("United Kingdom", "UK") val london = City("London", uk) val buckinghamPalace = Address("1", "Buckingham Place Road", london) val company = Company("Knoldus", buckinghamPalace) val canada = Country("Canada", "CA") val toronto = City("Toronto", canada) val mcMurray = Address("2", "610 McMurray Rd", toronto) val harmeet = User("Harmeet Singh", company, mcMurray) println("************ Before Move ************") println(harmeet) println("************ Move to Canada ************") val userCompany: Lens[User, Company] = GenLens[User](_.company) val userAddress = GenLens[User](_.address) val companyAddress = GenLens[Company](_.address) val addressCity = GenLens[Address](_.city) val cityCountry = GenLens[City](_.country) val countryCode = GenLens[Country](_.code) val countryName = GenLens[Country](_.name) val userCompanyCountryCode = userCompany composeLens companyAddress composeLens addressCity composeLens cityCountry composeLens countryCode val userCompanyCountryName = userCompany composeLens companyAddress composeLens addressCity composeLens cityCountry composeLens countryName val moveHarmeetCode = userCompanyCountryCode.set("CA")(harmeet) val moveHarmeetName = userCompanyCountryName.set("Canada")(moveHarmeetCode) println(moveHarmeetName) } }
No comments:
Post a Comment