[Haskell-cafe] Why distinct tyvars in instance declarations?

Josh Hoyt joshhoyt at gmail.com
Mon Jun 27 14:31:20 EDT 2005

On 6/26/05, Henning Thielemann <lemming at henning-thielemann.de> wrote:
> On Sun, 26 Jun 2005, Daniel Fischer wrote:
> > [...]
> > I don't know, why the tyvars must be distinct in Haskell 98,
> This is certainly to prevent from overlapping instances. An implementation
> for general (Either a b) could also be invoked when (Either String String)
> is requested.
> If it is really necessary to make the Either type an instance of something
> better use a data or a newtype definition.
> newtype EitherString = EitherString (Either String String)
> and declare an instance for EitherString.

I see why there is ambiguity between (Either a b) and (Either b b). In
fact, it seems rather obvious now. Thanks for your help.

Just to make sure I understand, and hopefully instructive for others
who run into the same difficulty:

class Foo a where
    frob :: a -> String

{- Illegal:

instance Foo (Either String String) where
    frob (Right x) = x
    frob (Left y) = y


-- Instead:

-- Option a:
-- Generic implementation in terms of other classes

instance (Show a, Show b) => Foo (Either a b) where
    frob (Right x) = show x
    frob (Left y) = show y

-- Option b:
-- Let the type system know that this is a specific case by defining a type

newtype EitherString = EitherString (Either String String)

instance Foo EitherString where
    frob (EitherString (Right x)) = x
    frob (EitherString (Left y)) = y

More information about the Haskell-Cafe mailing list