anchor.diff:                  |> Expr.update ("agg", <@ 0 @>)
   
               <@
  -                let tuple = %tuple
  +                let tuple = %expr
                   (% Expr.lam mkElementHasher) tuple
               @>
   
       | Shape.FSharpRecord (:? ShapeFSharpRecord<'T> as shape) ->
  -        fun (record : Expr<'T>) ->
  -            let mkFieldHasher record =
  -                shape.Fields
  -                |> Array.map (fun e -> stageMemberHash e record)
  -                |> Array.map (fun eh agg -> combineHash eh agg)
  -                |> Expr.update ("agg", <@ 0 @>)
  +        let mkFieldHasher record =
  +            shape.Fields
  +            |> Array.map (fun e -> stageMemberHash e record)
  +            |> Array.map (fun eh agg -> combineHash eh agg)
  +            |> Expr.update ("agg", <@ 0 @>)
                       
  -            <@
  -                let record = %record
  -                (% Expr.lam mkFieldHasher) record
  -            @>
  +        <@
  +            let record = %expr
  +            (% Expr.lam mkFieldHasher) record
  +        @>
   
       | Shape.FSharpUnion (:? ShapeFSharpUnion<'T> as shape) ->
  -        fun (u : Expr<'T>) ->
  -            let stageUnionCaseHasher 
  -                (union : Expr<'T>) (tag : Expr<int>)
  -                (case : ShapeFSharpUnionCase<'T>) =
  +        let stageUnionCaseHasher 
  +            (union : Expr<'T>) (tag : Expr<int>)
  +            (case : ShapeFSharpUnionCase<'T>) =
               
  -                case.Fields
  -                |> Array.map (fun c -> stageMemberHash c union)
  -                |> Array.map (fun fh agg -> combineHash fh agg)
  -                |> Expr.update ("agg", tag)
  -
  -            let stageUnionCaseHashers (u : Expr<'T>) (tag : Expr<int>) =
  -                shape.UnionCases
  -                |> Array.map (stageUnionCaseHasher u tag)
  -                |> Expr.switch tag
  -
  -            <@
  -                let union = %u
  -                let tag = (% Expr.lam shape.GetTagExpr) union
  -                (% Expr.lam2 stageUnionCaseHashers) union tag  
  -            @>
  +            case.Fields
  +            |> Array.map (fun c -> stageMemberHash c union)
  +            |> Array.map (fun fh agg -> combineHash fh agg)
  +            |> Expr.update ("agg", tag)
  +
  +        let stageUnionCaseHashers (u : Expr<'T>) (tag : Expr<int>) =
  +            shape.UnionCases
  +            |> Array.map (stageUnionCaseHasher u tag)
  +            |> Expr.switch tag
  +
  +        <@
  +            let union = %expr
  +            let tag = (% Expr.lam shape.GetTagExpr) union
  +            (% Expr.lam2 stageUnionCaseHashers) union tag  
  +        @>
   
       | _ -> failwithf "Unsupported shape %O" typeof<'T>
   
  -let mkHashCodeExpr<'T>() = stageHasher<'T>() |> Expr.lam |> Expr.cleanup
  +
  +
  +// Compilation code
  +
  +let mkHashCodeExpr<'T> () =
  +    fun e -> mkStagedHasher().Generate<'T> e
  +    |> Expr.lam
  +    |> Expr.cleanup
  +
   let mkHasher<'T> () = mkHashCodeExpr<'T>() |> QuotationEvaluator.Evaluate
   let decompileHasher<'T> () = mkHashCodeExpr<'T>() |> decompile
   
  
positive.code: //                agg 
  //            (h1 <<< 5) + h1 ||| agg
  //        agg 
  //    else invalidOp "invalid tag"
negative.code: 
  hasher2 [UA ; UC { A = 12 ; B = "test" }; UB "string" ]
  
  decompileHasher<Bar>()
  //fun t -> 
  //    let tag = t.Tag 
  //    if tag = 0 then tag 
  