Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I have to specify typeclass in function if it was declared in data definition?

If I have an ADT with specified typeclass restrictions I still have to specify the same typeclass for each function using this data type. What the reason for this and how can I reduce unnecessary typing?

E.g.:

data Eq a => C a = V a
g :: C a -> Bool
g (V a) = a == a

I got:

test.hs:32:13:
    No instance for (Eq a)
      arising from a use of `=='
    In the expression: a == a
    In an equation for `g': g (V a) = a == a
Failed, modules loaded: none.

While:

g :: Eq a => C a -> Bool

Works fine, but if I have a long chain of functions it becomes a burden to specify a typeclass everytime:

f :: Eq a => C a -> Bool
f a = g a
like image 953
Andrew Avatar asked Aug 12 '11 17:08

Andrew


People also ask

What is Typeclass in Haskell?

What's a typeclass in Haskell? A typeclass defines a set of methods that is shared across multiple types. For a type to belong to a typeclass, it needs to implement the methods of that typeclass. These implementations are ad-hoc: methods can have different implementations for different types.

How do you define data in Haskell?

The Data Keyword and Constructors In general, we define a new data type by using the data keyword, followed by the name of the type we're defining. The type has to begin with a capital letter to distinguish it from normal expression names. To start defining our type, we must provide a constructor.

What is the difference between type and data in Haskell?

Type and data type refer to exactly the same concept. The Haskell keywords type and data are different, though: data allows you to introduce a new algebraic data type, while type just makes a type synonym. See the Haskell wiki for details.

What does EQ mean in Haskell?

The Eq typeclass provides an interface for testing for equality. Any type where it makes sense to test for equality between two values of that type should be a member of the Eq class. All standard Haskell types except for IO (the type for dealing with input and output) and functions are a part of the Eq typeclass.


2 Answers

It's generally considered a bad idea to put a typeclass restriction on your ADT. Instead, leave it off and code normally using (==) wherever you have to. Your Eq a dependency will percolate up some of your functions and not others.

like image 106
Daniel Lyons Avatar answered Sep 28 '22 20:09

Daniel Lyons


Because the Haskell Report says so, basically. It's generally regarded as somewhat silly. Quoth the GHC User Guide:

All this behaviour contrasts with Haskell 98's peculiar treatment of contexts on a data type declaration (Section 4.2.1 of the Haskell 98 Report). In Haskell 98 the definition

data Eq a => Set' a = MkSet' [a]

gives MkSet' the same type as MkSet above. But instead of making available an (Eq a) constraint, pattern-matching on MkSet' requires an (Eq a) constraint! GHC faithfully implements this behaviour, odd though it is. But for GADT-style declarations, GHC's behaviour is much more useful, as well as much more intuitive.

Putting contexts on regular data definitions is discouraged and may (will?) be removed from the language at some point. Either put the context only on the function (which is what actually needs it, anyhow), or use GADT-style syntax to get the behavior you expected.

like image 23
C. A. McCann Avatar answered Sep 28 '22 20:09

C. A. McCann