
Hi Alexey, On 25/10/14 16:42, Alexey Muranov wrote:
i am trying to understand how typeclasses work. I know that they can be used as follows (from the manual):
data Foo = Foo {x :: Integer, str :: String}
instance Eq Foo where (Foo x1 str1) == (Foo x2 str2) = (x1 == x2) && (str1 == str2)
I am wondering, why is the following seemingly unambiguous syntax not allowed too?
data Foo = Foo { x :: Integer, str :: String }
instance Eq Foo
(Foo x1 str1) == (Foo x2 str2) = (x1 == x2) && (str1 == str2)
This case is obviously unambiguous, but what is the general rule? Is the presence of the Foo data constructor important? What if I wrote the following, which would be a perfectly good instance method: foo1 == foo2 = (x foo1 == x foo2) && (str foo1 == str foo2) In general, should the compiler be doing type inference to determine which instance a declaration belongs to? In principle, the language could permit instance methods to be detached from the instances themselves, but I don't think it should.
If it was allowed, it seems that it could also be applied to records:
class HasName r where name :: r -> String
data Bird = Bird { name :: String, wingNumber :: Integer } data Person = Person { name :: String, likesBirds :: Bool }
instance HasName Bird instance HasName Person
Note that this currently would only work if you declare Bird and Person in different modules. I'm not convinced that saving one line of boilerplate in the instance declarations is worth it. On the topic of records in particular, you may be interested in the work on OverloadedRecordFields [1], which might (or might not) appear in GHC 7.10. Cheers, Adam [1] https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields -- Adam Gundry, Haskell Consultant Well-Typed LLP, http://www.well-typed.com/