data Num a => Bundle a = Bundle a a

instance Num a => Show (Bundle a) where
    showsPrec p (Bundle x x') = showsPrec p [x,x']

instance Num a => Eq (Bundle a) where
    (Bundle x x') == (Bundle y y') = (x == y)

lift z = Bundle z 0

instance Num a => Num (Bundle a) where
    (Bundle x x') + (Bundle y y') = Bundle (x + y) (x' + y')
    (Bundle x x') * (Bundle y y') = Bundle (x * y) (x * y' + x' * y)
    fromInteger z = lift (fromInteger z)

instance Fractional a => Fractional (Bundle a) where
    fromRational z = lift (fromRational z)

d f x = let (Bundle y y') = f (Bundle x 1) in y'

constant_one x = d (\y -> (lift x) + y) 1

should_be_one_a = d (\x -> x * (constant_one x)) 1
should_be_one_b = d (\x -> x * 1               ) 1

violation_of_referential_transparency = should_be_one_a /= should_be_one_b
