anchor.diff:          { new IEqualityComparer<'a> with
               member __.Equals(t,t') = cmp t t'
               member __.GetHashCode t = hash t } |> unbox<IEqualityComparer<'T>>
  +
  +    let mkMembersComparer (members : #IShapeMember<'DeclaringType> []) =
  +        let mkMemberComparer (shape : IShapeMember<'DeclaringType>) =
  +            shape.Accept { new IMemberVisitor<'DeclaringType, IEqualityComparer<'DeclaringType>> with
  +                member __.Visit (shape : ShapeMember<'DeclaringType, 'FieldType>) =
  +                    let fc = mkEqualityComparer<'FieldType>()
  +                    { new IEqualityComparer<'DeclaringType> with
  +                        member __.Equals(d1, d2) = fc.Equals (shape.Project d1, shape.Project d2)
  +                        member __.GetHashCode d = fc.GetHashCode (shape.Project d) }
  +            }
  +
  +        let memberComps = members |> Array.map mkMemberComparer
  +        { new IEqualityComparer<'DeclaringType> with
  +            member __.Equals(d1, d2) = memberComps |> Array.forall (fun ec -> ec.Equals(d1,d2))
  +            member __.GetHashCode d =
  +                let mutable hash = 0
  +                for ec in memberComps do hash <- combine hash (ec.GetHashCode d)
  +                hash }
   
       match TypeShape.Create<'T>() with
       | Shape.Unit -> wrap (fun () -> 0) (fun () () -> true)
  
positive.code:                     wrap (hash 0) equals
          }
  
      | Shape.Array s ->
          s.Accept {
              new IArrayVisitor<IEqualityComparer<'T>> with
                  member __.Visit<'a> () =
                      let tc = mkEqualityComparer<'a>()
                      let hash (xs : 'a []) =
                          let mutable h = 0
  
negative.code:                     wrap hash equals    
          }
  
      | Shape.Tuple s ->
          s.Accept {
              new ITupleVisitor<IEqualityComparer<'T>> with
                  member __.Visit (shape : ShapeTuple<'Tuple>) =
                      mkMembersComparer shape.Elements |> unbox
          }
  
      | Shape.FSharpRecord s ->
          s.Accept {
              new IFSharpRecordVisitor<IEqualityComparer<'T>> with
                  member __.Visit (shape : ShapeFSharpRecord<'Record>) =
                      mkMembersComparer shape.Fields |> unbox
          }
  
      | Shape.FSharpUnion s ->
          s.Accept {
              new IFSharpUnionVisitor<IEqualityComparer<'T>> with
                  member __.Visit (shape : ShapeFSharpUnion<'Union>) =
                      let unionCaseComparers = shape.UnionCases |> Array.map (fun uc -> mkMembersComparer uc.Fields)
                      { new IEqualityComparer<'Union> with
                          member __.Equals (u1,u2) =
                              match shape.GetTag u1, shape.GetTag u2 with
                              | t1, t2 when t1 <> t2 -> false
                              | tag, _ -> unionCaseComparers.[tag].Equals(u1,u2)
  
                          member __.GetHashCode u = 
                              let tag = shape.GetTag u
                              combine tag (unionCaseComparers.[tag].GetHashCode u) } |> unbox
          }
  
      | Shape.FSharpSet s ->
  