gseitz/Lensed


in your case

Language: Scala


Description

Scala compiler plugin that generates scalaz.Lenses in companion objects for case class fields.

Disclaimer

This compiler plugin is in a VERY early stage.

USE AT YOUR OWN RISK

Features

Completed:

Todo:

  • Cache lenses in a val and add asInstanceOf casts to the def's body.

Quickstart

git clone https://github.com/gseitz/Lensed.git
cd Lensed
sbt "project usage" console

The last line compiles the projects in this order annotation, plugin (package), testCaseClasses, usage and presents you with a scala REPL ready for playing around:

import lensed.test.Persons._

Now you can play around with some predefined persons.

Restrictions

Because of certain restrictions for compiler plugins (specifically, not being able to run between namer and typer phase), it is not possible to use the created lenses in the same compilation pass (read module, project, ...).

The obvious workaround is to put all case classes for which you want lenses to be generated into a separate project/submodule and have other projects depend on it. The compiler plugin only needs to be active for the project with the case classes.

Caveats

Because IDEA uses its own parser for scala code, it doesn't know about the generated lenses and will mark the code with errors.

Example

Project A

    case class Person(name: String, address: Address)
    case class Address(city: String)

The following code will be generated:

    object Person {
      def name: Lens[Person, String] = Lens(_.name, (p, n) => p.copy(name = n))
      def address: Lens[Person, Address] = Lens(_.address, (p, a) => p.copy(address = a))

      class PersonW[A](l: Lens[A, Person]) {
        def name: Lens[A, String] = l andThen Person.name
        def address: Lens[A, Address] = l andThen Person.address
      }

      implicit def lens2personW[A](l: Lens[A, Person]): PersonW[A] = new PersonW(l)
    }

    object Address {
      def city: Lens[Address, String] = Lens(_.city, (p, s) => p.copy(city = s))

      class AddressW[A](l: Lens[A, Address]) {
        def city: Lens[A, String] = l andThen Address.city
      }

      implicit def lens2addressW[A](l: Lens[A, Address]): AddressW[A] = new AddressW(l)
    }

Usage Project B

    val yankee = Person("John", Address("NYC"))
    val mounty = Person.address.city.set(yankee, "Montreal")
    Person.address.city.get(mounty) // == "Montreal"
    val cityLens: scalaz.Lens[Person, String] = Person.address.city

Project Statistics

Sourcerank 4
Repository Size 136 KB
Stars 65
Forks 3
Watchers 4
Open issues 0
Dependencies 0
Contributors 1
Tags 3
Created
Last updated
Last pushed

Top Contributors See all

Gerolf Seitz

Recent Tags See all

0.5 August 01, 2011
0.2 July 18, 2011
0.1 July 16, 2011

Interesting Forks See all

MoixaEnergy/Lensed
in your case
Scala - Last pushed - 1 stars

Something wrong with this page? Make a suggestion

Last synced: 2017-11-24 18:58:45 UTC

Login to resync this repository