Is there a way to automatically derive instances for Eq (and show) for Power
?
I managed to find http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/deriving.html but I could not locate any explanation relevant to the code below.
In addition, if there is a better practice for the effect created below I am open to suggestions as I am new to haskell and functional programming.
{-# LANGUAGE ExistentialQuantification #-}
class Country a
instance Country CountrySet1
data CountrySet1 =
Belgium |
Algeria
deriving (Show)
data Power =
forall a. Country a => Power a |
Netural |
Water
deriving (Eq, Show)
EDIT: I know that this is kind of a hack, but since it is almost all done with prelude function it should get correct results, unless there is completely malicious code (which is a most always the case with the "open world assumption").
class Country a where
show :: a -> String
instance Country CountrySet1 where
show a = Prelude.show a
data CountrySet1 =
England |
Turkey
deriving (Show)
data Power =
forall a. Country a => Power a |
Netural |
Water
instance Show Power where
show (Power b) = "Power" ++ Main.show b
show (Netural) = "Netural"
show (Water) = "Water"
instance Eq Power where
(==) a b = Prelude.show a == Prelude.show b
I believe GHC currently does not support deriving instances for most complicated types (that is, types that can only be written with extensions on). However, there is a slightly cleaner approach to writing this instance manually than the one you suggested here. Rather than creating a new Main.show
and (Main.==)
, you can dispatch to Prelude.show
and (Prelude.==)
, provided that you tell the compiler this is okay. On way to do this is to make Show
and Eq
superclasses of Country
:
class (Show a, Eq a) => Country a
However, as we learned from the history of Num
, you usually want to shift that burden elsewhere. So, your other option is to put those constraints in your existential:
data Power = forall a. (Show a, Eq a, Country a) => Power a | ...
Taking one additional step back, it's also quite possible that you simply shouldn't use existentials here; they are quite often unnecessary. It's hard to give more targeted refactoring advice without a bit more context, though.