Isn't that funny?...
class SuperType a b c | a b -> c
class Coerce a b where
coerce :: a -> b
instance (Coerce a c, Coerce b d) => Coerce (a, b) (c, d) where
coerce (a, b) = (coerce a, coerce b)
coerceSuper :: (SuperType a b c, Coerce a c, Coerce b c) => (a, b) -> (c, c)
coerceSuper = coerce
instance (Integral a, Integral b) => SuperType a b Integer
instance Integral a => Coerce a Integer where coerce = toInteger
class (Integral a, Num a) => NumCoerce a
instance (Integral a, Num a) => NumCoerce a
data ANum = forall a . NumCoerce a => ANum a
instance Show ANum where showsPrec n (ANum a) = showsPrec n a
instance Eq ANum where
(ANum a) == (ANum b) = (uncurry (==) . coerceSuper) (a,b)
instance Num ANum where
(ANum a) + (ANum b) = (ANum . uncurry (+) . coerceSuper) (a,b)
(ANum a) * (ANum b) = (ANum . uncurry (*) . coerceSuper) (a,b)
(ANum a) (ANum b) = (ANum . uncurry () . coerceSuper) (a,b)
negate (ANum a) = ANum (negate a)
abs (ANum a) = ANum (abs a)
signum (ANum a) = ANum (signum a)
fromInteger = ANum
One thing I really miss is nice way to create type-sets like
NumCoerce a
No comments:
Post a Comment