data Expr = Value Integer | Signum Expr | Abs Expr | Add Expr Expr | Mul Expr Expr deriving (Show, Eq) instance Num Expr where a + b = Add a b a * b = Mul a b signum = Signum abs = Abs fromInteger = Value f1 x y = x * y f2 x y = x + y -- f1 1 2 :: Expr => Mul (Value 1) (Value 2) -- f1 1 2 :: Expr => Add (Value 1) (Value 2) f3 x y = a * a where a = x + y -- f3 1 2 :: Expr => Mul (Add (Value 1) (Value 2)) (Add (Value 1) (Value 2)) -- How to recover the sharing? -- http://zwizwa.be/-/meta/20110114-130928