G'day all.
Quoting Henning Thielemann <[EMAIL PROTECTED]>:
> I like to hear some opinions about how to implement class method defaults.
In this case, don't. Use instance defaults instead.
class (Eq a) => Ring a where
(*),(+),(-) :: a -> Integer
zero, one :: a
negate :: a -> a
negate = (zero -)
isZero :: a -> Bool
isZero = (==zero)
class (Ring a) => RingWithNorm a where
nu :: a -> Integer
class (RingWithNorm a) => EuclideanDomain a where
divMod :: a -> a -> (a,a)
class (RingWithNorm a) => GCD a where
gcd :: a -> a -> a
instance (EuclideanDomain a) => GCD a where
gcd = {- Euclidean GCD algorithm; detail omitted -}
Then if you have some other domain where GCD applies, you can create
other instances as needed:
class (RingWithNorm a) => SteinDomain a where
smallestPrime :: a
steinDecompose :: a -> Maybe (a,a)
-- scale p q = p/q
-- where nu q < nu smallestPrime
scale :: a -> a -> a
instance (SteinDomain a) => GCD a where
gcd a b
| nu a < nu b = gcd b a
| a == b = a
| otherwise = case (steinDecompose a, steinDecompose b) of
(Nothing,_) -> b
(_,Nothing) -> a
(Just (pa,ca), Just (pb,cb))
| isZero ca && isZero cb -> smallestPrime * gcd pa pb
| isZero cb -> gcd a pb
| otherwise -> gcd (pa - scale (ca*pb) cb) b
Cheers,
Andrew Bromage
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe