Real World Haskell has this example:
class BasicEq3 a where
isEqual3 :: a -> a -> Bool
isEqual3 x y = not (isNotEqual3 x y)
isNotEqual3 :: a -> a -> Bool
isNotEqual3 x y = not (isEqual3 x y)
instance BasicEq3 Bool
And when I run it in GHCI:
#> isEqual3 False False
out of memory
So, you have to implement at least one of the 2 methods or it will loop. And you get the flexibility of choosing which one, which is neat.
The question I have is, is there a way to get a warning or something if didn't override enough of the defaults and the defaults form a loop? It seems strange to me that the compiler that is so crazy smart is fine with this example.
I think it's perfectly fine for GHC to issue a warning in case of an "unbroken" cyclic dependency. There's even a ticket along those lines: http://hackage.haskell.org/trac/ghc/ticket/6028
Just because something is "undecidable" doesn't mean no instance of the problem can be solved effectively. GHC (or any other Haskell compiler) already has quite a bit of the information it needs, and it'd be perfectly possible for it to issue a warning if the user is instantiating a class without "breaking" the cyclic dependency. And if the compiler gets it wrong in the rare cases as exemplified in previous posts, then the user can have a -nowarnundefinedcyclicmethods
or a similar mechanism to tell GHC to be quiet. In nearly every other case, the warning will be most welcome and would add to programmer productivity; avoiding what's almost always a silly bug.
No, I'm afraid GHC doesn't do anything like that. Also that isn't possible in general.
You see, the methods of a type class could be mutually recursive in a useful way. Here's a contrived example of such a type class. It's perfectly fine to not define either sumOdds
or sumEvens
, even though their default implementations are in terms of each other.
class Weird a where
measure :: a -> Int
sumOdds :: [a] -> Int
sumOdds [] = 0
sumOdds (_:xs) = sumEvens xs
sumEvens :: [a] -> Int
sumEvens [] = 0
sumEvens (x:xs) = measure x + sumOdds xs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With