[Haskell-cafe] type classes
Dan Doel
dan.doel at gmail.com
Wed Jul 2 21:57:22 EDT 2008
On Wednesday 02 July 2008, Cotton Seed wrote:
> Hi everyone,
>
> I'm working on a computational algebra program and I've run into a problem.
> In my program, I have types for instances of algebraic objects, e.g. ZModN
> for modular integers, and types for the objects themselves, e.g. ZModNTy
> for the ring of modular integers.
>
> Now, I want to subclass ZModNTy from something like
>
> class RingTy a b where
> order :: a -> Integer
> units :: a -> [b]
>
> where `a' represents algebraic object, and `b' the type of instances of
> that object. I want an instance
>
> instance RingTy ZModNTy ZModN where ...
>
> but then code that only uses order fails with errors like
>
> No instance for (RingTy ZModNTy b)
> arising from a use of `order' at Test2.hs:16:8-15
>
> since there is no constraint on the second type variable.
>
> I think what I really want is
>
> class RingTy a where
> order :: a b -> Integer
> units :: a b -> [b]
>
> but this doesn't work either since ZModNTy is not parametric in its type
> like, say, `Polynomial a' is.
>
> Is this a common problem? Is there a standard way to handle it?
Correct me if I'm wrong, but wouldn't the a uniquely determine the b? In that
case, you'd probably want a functional dependency:
class RingTy a b | a -> b where
order :: a -> Integer
units :: a -> [b]
This solves the problem with order, because with multi-parameter type classes,
all the variables should be determined for a use of a method. Since b is not
involved with order, it could be anything, so it's rather ambiguous. The
functional dependency solves this by uniquely determined b from a, so order
is no longer ambiguous.
Alternately, with the new type families, this can become:
class RingTy a where
type RingElem a :: *
order :: a -> Integer
units :: a -> [RingElem a]
Or something along those lines.
Hope that helps.
-- Dan
More information about the Haskell-Cafe
mailing list