Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

noob "Duplicate instance declarations" (again)

Tags:

haskell

yes...sorry this has been asked before, but usually about something so specific and complex that it in incomprehensible

with a naïve OO head...we go....

class Animal a where

class Mammal m where

class Insect i where

instance (Mammal m) => Animal m

instance (Insect i) => Animal i

and ghc goes

Duplicate instance declarations:

  instance forall (k :: BOX) (m :: k). Mammal m => Animal m
  instance forall (k :: BOX) (i :: k). Insect i => Animal i

and you look it up...and there is a solution using witness types, that I could probably get to work BUT....I don't understand what the problem?

allegedly the compiler matches the right hand side and bla bla...?

I don't understand....I think I'm saying...if I have a type of typeclass Dog...then its also of typeclass Animal...so if I call methods foo etc then this is how to do it (in terms of a Dog)

I'm missing something

like image 534
nichom Avatar asked Mar 15 '23 21:03

nichom


1 Answers

Yup, you're missing something. Here's how you should have defined your class hierarchy:

class Animal a where
class Animal a => Mammal a where
class Animal a => Insect a where

This is how you express superclass relationships. Instance declarations are for actually making types instances of your classes.

instance Animal Ant where
instance Insect Ant where

What goes wrong in the original

You wrote

instance (Mammal m) => Animal m

instance (Insect i) => Animal i

Haskell requires that there be only one instance for each class and type. Thus is determined only from the part to the right of the =>. So it sees two declarations for

instance Animal a

and complains. You could have

instance Animal (Maybe a)

and also

instance Animal Int

But if you have

instance Animal a

then you can't have any other instance declarations for Animal.

like image 104
dfeuer Avatar answered Mar 25 '23 01:03

dfeuer