Hash consing for arbitrary Haskell data types