anchor.diff:  
           match shapeof<'T>, path with
           | _, [] -> wrap { get = id<'F> ; set = fun (_:'F) (y:'F) -> y }
  -        | Shape.FSharpList s, Item i :: rest ->
  -            s.Accept { new IFSharpListVisitor<Lens<'T,'F>> with
  -                member __.Visit<'t> () =
  -                    let inner = mkLensAux<'t, 'F> rest
  -                    wrap {
  -                        get = fun (ts : 't list) -> inner.get ts.[i]
  -                        set = fun (ts : 't list) (f : 'F) -> ts |> List.mapi (fun j t -> if j = i then inner.set t f else t)
  -                    }
  -            }
  -
           | Shape.FSharpOption s, Property "Value" :: rest ->
               s.Accept { new IFSharpOptionVisitor<Lens<'T,'F>> with
                   member __.Visit<'t> () =
  
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:                     }
              }
  
          | Shape.Array s, Item(:? int as i) :: rest when s.Rank = 1 ->
              s.Accept { new IArrayVisitor<Lens<'T,'F>> with
                  member __.Visit<'t> _ =
                      let inner = mkLensAux<'t, 'F> rest
  