0

In my project I encountered a situation where I need to perform nested update on immutable object which is an instance of case class.

Firstly I just wanted to use copy function provided by the case classes but then I stumbled upon lenses. I looked up Shapeless and Scalaz implementations and decided I will try to use lenses from Shapeless, so I grabbed the dependency, added "com.chuusai" % "shapeless" % "2.0.0" cross CrossVersion.full to my build.sbt and tried to write something simple, based on available example on GitHub: https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#boilerplate-free-lenses-for-arbitrary-case-classes.

object LenseExamples extends App {
  import shapeless._

  // A pair of ordinary case classes ...
  case class Address(street : String, city : String, postcode : String)
  case class Person(name : String, age : Int, address : Address)

  // Some lenses over Person/Address ...
  val nameLens     = Lens[Person] >> 0
  val ageLens      = Lens[Person] >> 1
  val addressLens  = Lens[Person] >> 2
  val streetLens   = Lens[Person] >> 2 >> 0
  val cityLens     = Lens[Person] >> 2 >> 1
  val postcodeLens = Lens[Person] >> 2 >> 2

  val person = Person("Joe Grey", 37, Address("Southover Street", "Brighton", "BN2 9UA"))

  val age1 = ageLens.get(person)
}

but during the compilation I am getting errors like:

inferred type arguments [Nothing,Int] do not conform to method >>'s type parameter bounds [L <: shapeless.HList,N <: shapeless.Nat]
  val nameLens     = Lens[Person] >> 0
                                  ^
type mismatch;
 found   : Int(0)
 required: N
  val nameLens     = Lens[Person] >> 0
                                     ^
could not find implicit value for parameter iso: shapeless.Iso[api.LenseExamples.Person,L]
  val nameLens     = Lens[Person] >> 0
                                  ^                                     
                                  ^ 

probably I am missing something obvious because I copy-pasted an example from wiki.

EDIT: After comment from Travis I generated dependency graph for my project using https://github.com/jrudolph/sbt-dependency-graph and I observed that spray-routing is already including shapeless library:

[info]   +-io.spray:spray-routing:1.3.0 [S]
[info]   | +-com.chuusai:shapeless_2.10:1.2.4 [S]
[info]   | | +-org.scala-lang:scala-library:2.10.0 (evicted by: 2.10.4)
[info]   | | +-org.scala-lang:scala-library:2.10.3 (evicted by: 2.10.4)

So I removed my dependency and tried the example from https://github.com/milessabin/shapeless/blob/scala-2.9.x/examples/src/main/scala/shapeless/examples/lenses.scala and now it works properly.

Andna
  • 6,539
  • 13
  • 71
  • 120

1 Answers1

1

Your example should work if you replace Lens[Person] with lens[Person] (ie. lower case l) throughout. Why? Your shapeless dependency is pointing you at a just-published, but not yet announced or fully documented shapeless-2.0.0 final release. Shh ... don't tell anyone ;-)

Miles Sabin
  • 23,015
  • 6
  • 61
  • 95
  • Hey, thanks for answer. It turned out that my problem was that `spray-routing` already pulled `shapeless` library to my project, but in different version: `1.2.4`. I looked on the example for this version and now lenses work ok. – Andna Apr 10 '14 at 22:42