anchor.diff:           Builder.emit (OpCodes.Ldarg_1) >>
            Builder.emit (OpCodes.Call, getMethod)
       let rec emitLoadAddr arg i =
  -      if i = 0 then
  -        Builder.emit arg
  -      else
  -        let loadPrev = emitLoadAddr arg (i-1)
  -        if i <> products.Length-1 then
  -          loadPrev >>
  -          Builder.emit (OpCodes.Ldflda, getField products.[i-1] "Rest")
  -        else
  -          loadPrev
  -    let emitStore i =
  -      if products.Length = 1 then
  -        Builder.emit (OpCodes.Stobj, products.[i])
  -      elif i < products.Length-1 then
  -        Builder.emit (OpCodes.Stfld, getField products.[i] "Elem")
  -      else
  -        Builder.emit (OpCodes.Stfld, getField products.[i-1] "Rest")
  +      if i = 0
  +      then Builder.emit arg
  +      else emitLoadAddr arg (i-1)
  +           >> if i <> products.Length-1
  +              then Builder.emit (OpCodes.Ldflda, getField products.[i-1] "Rest")
  +              else id
  +    let emitLoadOrStore objOp fldOp i =
  +      if products.Length = 1
  +      then Builder.emit (objOp, products.[i])
  +      else Builder.emit (fldOp, if i < products.Length-1
  +                                then getField products.[i] "Elem"
  +                                else getField products.[i-1] "Rest")
  +    let emitStore = emitLoadOrStore OpCodes.Stobj OpCodes.Stfld
       let emitCopy i =
         emitLoadAddr OpCodes.Ldarg_2 i >> emitGet i >> emitStore i
       let rec emitCopies n =
  -      let copyThis = emitCopy (n-1)
  -      if n > 1 then emitCopies (n-1) >> copyThis else copyThis
  +      if n > 1 then emitCopies (n-1) else id
  +      >> emitCopy (n-1)
       let emitLoad i =
         emitLoadAddr OpCodes.Ldarg_1 i >>
  -      if products.Length = 1 then
  -        Builder.emit (OpCodes.Ldobj, products.[i])
  -      elif i < products.Length-1 then
  -        Builder.emit (OpCodes.Ldfld, getField products.[i] "Elem")
  -      else
  -        Builder.emit (OpCodes.Ldfld, getField products.[i-1] "Rest")
  +      emitLoadOrStore OpCodes.Ldobj OpCodes.Ldfld i
       let rec emitLoads n =
  -      let loadThis = emitLoad (n-1)
  -      if n > 1 then emitLoads (n-1) >> loadThis else loadThis
  +      if n > 1 then emitLoads (n-1) else id
  +      >> emitLoad (n-1)
       Builder.overrideMethod "Extract"
        typeof<Void>
        [|t; products.[0].MakeByRefType ()|]
  -     (if props.Length > 0 then
  -        emitCopies props.Length >>
  -        Builder.emit (OpCodes.Ret)
  -      else
  -        Builder.emit (OpCodes.Ret)) >>= fun () ->
  +     (if props.Length > 0 then emitCopies props.Length else id
  +      >> Builder.emit (OpCodes.Ret)) >>= fun () ->
       Builder.overrideMethod "Create"
        t
        [|products.[0].MakeByRefType ()|]
  -     (if props.Length > 0 then
  -        emitLoads props.Length >>
  -        emitCtor >>
  -        Builder.emit (OpCodes.Ret)
  -      else
  -        emitCtor >>
  -        Builder.emit (OpCodes.Ret))
  +     (if props.Length > 0 then emitLoads props.Length else id
  +      >> emitCtor
  +      >> Builder.emit (OpCodes.Ret))
   
     let asPairsField (t: Type)
                      (emitCtor: ILGenerator -> ILGenerator)
  
positive.code:                              (props: array<PropertyInfo>)
                               (products: array<Type>) =
      let getField (t: Type) name =
        match t.GetField name with // Only public is ok here.
         | null -> failwithf "The %A type has no field named \"%s\"" t name
         | field -> field
      let emitGet i =
  
negative.code:     let t = typeof<'t>
  
      match
        if FSharpType.IsRecord (t, B.Public) then
          let fields = FSharpType.GetRecordFields (t, B.Public)
          let products =
            fields |> Array.map (fun p -> p.PropertyType) |> Products.products
  
          Builder.metaType typeof<Record<'t>> [||]
           (Products.asPairsField t
             (Builder.emit
               (OpCodes.Newobj,
                FSharpValue.PreComputeRecordConstructorInfo (t, B.Public)))
             fields
             products
             (Builder.forTo 0 (fields.Length-1) <| fun i ->
                Builder.metaField
                 (typedefof<Field<_, _, _>>.MakeGenericType
                   [|fields.[i].PropertyType; products.[i]; t|])
                 [|box i; fields.[i].Name; box fields.[i].CanWrite|]
                 (Builder.overrideGetMethod "Get" t fields.[i] >>= fun () ->
                  Builder.overrideSetMethodWhenCanWrite "Set" fields.[i])))
        elif FSharpType.IsUnion (t, B.Public) then
          let cases = FSharpType.GetUnionCases (t, B.Public)
          let caseFields = cases |> Array.map (fun case -> case.GetFields ())
          let caseProducts =
            caseFields
            |> Array.map
                (Array.map (fun p -> p.PropertyType) >> Products.products)
          let choices =
            caseProducts |> Array.map (fun ts -> ts.[0]) |> Unions.choices
  
          Builder.metaType typeof<Union<'t>> [||]
           (Unions.asChoicesField t choices
  