If I have an ADT with specified typeclass restricti开发者_StackOverflowons 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
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.
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.
精彩评论