anchor.diff:          | _ -> invalidArg "expr" "lens expressions must be lambda literals"
   
       let rec mkLensAux<'T, 'F> (path : Path) : Lens<'T, 'F> =
  -        let wrap (l : Lens<'a,'b>) : Lens<'T, 'F> = unbox l
  +        let wrap (l : Lens<'a, 'F>) : Lens<'T, 'F> = unbox l
   
  -        let nest chain (m : IShapeWriteMember<'T>) =
  +        let nest path (m : IShapeWriteMember<'T>) =
               m.Accept { new IWriteMemberVisitor<'T, Lens<'T, 'F>> with
                   member __.Visit<'F0> (m : ShapeWriteMember<'T, 'F0>) =
  -                    let inner = mkLensAux<'F0, 'F> chain
  +                    let inner = mkLensAux<'F0, 'F> path
                       {
                           get = fun (t:'T) -> inner.get (m.Project t)
                           set = fun (t:'T) (f:'F) -> m.Inject t (inner.set (m.Project t) f)
  
positive.code:     type Path = Node list
      and Node =
          | Property of string
          | Item of int
  
      // converts a quotation of the form <@ fun x -> x.Foo.Bar.[0].Baz @> into a path
      let extractPath (e : Expr<'T -> 'F>) : Path =
          let rec aux v acc e =
              match e with
              | Var v' when v = v' -> acc
              | PropertyGet(Some o, p, [Value((:? int as i), _)]) when p.Name = "Item" -> aux v (Item i :: acc) o
              | PropertyGet(Some o, p, []) -> aux v (Property p.Name :: acc) o
              | Call(None, m, [o ; Value(:? int as i, _)]) when m.Name = "GetArray" && o.Type.IsArray && e.Type = o.Type.GetElementType() -> aux v (Item i :: acc) o
              // we support tuples, as they are often used to encode fields in erased type providers
  
negative.code: 
          match shapeof<'T>, path with
          | _, [] -> wrap { get = id<'F> ; set = fun (_:'F) (y:'F) -> y }
          | Shape.FSharpOption s, Property "Value" :: rest ->
              s.Accept { new IFSharpOptionVisitor<Lens<'T,'F>> with
                  member __.Visit<'t> () =
  