{"id":35102371,"url":"https://github.com/monadplus/scala-lenses","last_synced_at":"2026-05-20T01:35:17.798Z","repository":{"id":44128599,"uuid":"182801271","full_name":"monadplus/scala-lenses","owner":"monadplus","description":"Diving into Optics through https://github.com/julien-truffaut/Monocle.","archived":false,"fork":false,"pushed_at":"2022-02-12T02:14:09.000Z","size":5376,"stargazers_count":4,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-29T17:56:38.734Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monadplus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-22T14:10:10.000Z","updated_at":"2020-09-04T20:30:33.000Z","dependencies_parsed_at":"2022-09-03T20:21:22.182Z","dependency_job_id":null,"html_url":"https://github.com/monadplus/scala-lenses","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/monadplus/scala-lenses","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Fscala-lenses","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Fscala-lenses/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Fscala-lenses/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Fscala-lenses/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monadplus","download_url":"https://codeload.github.com/monadplus/scala-lenses/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monadplus%2Fscala-lenses/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28081475,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-27T02:00:05.897Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-27T17:02:43.005Z","updated_at":"2025-12-27T17:03:50.894Z","avatar_url":"https://github.com/monadplus.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# The magic of composition\n\nDuring this talk, we are going to dive into _Monocle_ and\nunravel the mystery surrounding __optics__.\n\nSlides [here](https://monadplus.github.io/scala-lenses/).\n\n## Public\n\nThis talk is aimed for developers with basic notion of:\n - Scala\n - Functional programming\n\nThe examples are in written in Scala so a basic notion of the syntax is assumed.\n\nIf you are not acquainted with the words `Functor, Appicative, Foldable, Traverse`\nI would recommend visiting first the [cats](https://typelevel.org/cats/typeclasses.html)\nand [typeclassopedia](https://wiki.haskell.org/Typeclassopedia) and get a basic notion of these concepts.\n\n## Motivation\n\n```scala\ncase class Street(number: Int, name: String)\ncase class Address(city: String, street: Street)\ncase class Company(name: String, address: Address)\ncase class Employee(name: String, company: Company)\n\nval employee = Employee(\"john\", Company(\"awesome inc\", Address(\"london\", Street(23, \"high street\"))))\n```\n\nOld plain scala:\n```scala\nemployee.copy(\n  company = employee.company.copy(\n    address = employee.company.address.copy(\n      street = employee.company.address.street.copy(\n        name = employee.company.address.street.name.capitalize // luckily capitalize exists\n      )\n    )\n  )\n)\n```\n\nWith lenses:\n```scala\n(company composeLens\n address composeLens\n street composeLens streetName).modify(_.capitalize)(employee)\n```\n\n## Libraries\n\nLenses provides __more composable__ versions of the abstractions you already known how to use in Scala/Haskell.\n\n - [monocle](https://github.com/julien-truffaut/Monocle) (scala)\n - [lenses](https://github.com/ekmett/lens#lens-lenses-folds-and-traversals) (haskell)\n\nBoth libraries provides rich APIs to work with lenses and a battery of utilities to make your life easier.\nLenses is based on Van Laarhoven optics while Monocle uses an alternative encoding. The reason behind not using\nVan Laarhoven nor profunctor optics is because they are inefficient in scala and not well supported by the language\n(scala does not support N-rank types).\n\n\n## Hierarchy\n\n![Simplified Class Diagram](https://raw.github.com/julien-truffaut/Monocle/master/image/class-diagram.png)\n\n_Monocle lenses hierarchy_\n\n![Class Diagram](http://i.imgur.com/ALlbPRa.png)\n\n_Lenses hierarchy in haskell_\n\n## Composition\n\nThe result is their lowest upper bound in the hierarchy (or an error if that bound doesn't exist).\n\n|               | Getter     | Iso        | Lens       | Optional     | Prism      | Setter     | Traversal     |\n| ------------- |:----------:|:----------:|:----------:|:------------:|:----------:|:----------:|:-------------:|\n| **Getter**    | **Getter** | Getter     | Getter     | Fold         | Fold       | -          | Fold          |\n| **Iso**       | Getter     | **Iso**    | Lens       | Optional     | Prism      | Setter     | Traversal     |\n| **Lens**      | Getter     | Lens       | **Lens**   | Optional     | Optional   | Setter     | Traversal     |\n| **Optional**  | Fold       | Optional   | Optional   | **Optional** | Optional   | Setter     | Traversal     |\n| **Prism**     | Fold       | Prism      | Optional   | Optional     | **Prism**  | Setter     | Traversal     |\n| **Setter**    | -          | Setter     | Setter     | Setter       | Setter     | **Setter** | Setter        |\n| **Traversal** | Fold       | Traversal  | Traversal  | Traversal    | Traversal  | Setter     | **Traversal** |\n\n## Credits:\n - https://github.com/julien-truffaut/Monocle (J. Truffaut et al)\n - https://hackage.haskell.org/package/lens (E. Kmett)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonadplus%2Fscala-lenses","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonadplus%2Fscala-lenses","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonadplus%2Fscala-lenses/lists"}