
G'day all.
Quoting Henning Thielemann
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