On Wed, 10 Sep 2003 10:26:04 +0100, Robert Ennals <Robert.Ennals@cl.cam.ac.uk> wrote:
class Wibble a where wibble :: a -> Int wobble :: a -> String set_wibble :: Int -> a -> a set_wobble :: String -> a -> a
data Foo = Foo {wibble :: Int, wobble :: String} deriving Wibble
The Wibble class defines selector and updater functions for fields called wibble and wobble.
When I define the datatype Foo, I give it fields called wibble and wobble, which will define the functions in Wibble. If I say "deriving Wibble" then the type system acknowledges that these functions are implementing the class Wibble. If I had not derived Wibble then there would have been a name clash.
What would you do if Wibble had more functions than just those 4? You'd need somewhere to put the implementations of the other functions for Foo.
I guess there are three options. A: Don't allow records to be instances of such classes. B: Add extra syntax to allow this. E.g something like this: data Foo = Foo {wibble :: Int} deriving Wibble where wobble x = "hello" set_wobble w x = x C: Declare instances using normal instance declarations: e.g. data Foo = Foo {wibble :: Int} instance Wibble Foo where wobble = x "hello" set_wobble w x = x -- wibble and set_wibble done automatically. This has the weakness that the compiler has to see the instance declaration when compiling the type declaration for Foo in order to know that the names are not clashing. It is however possibly the best option. -Rob