2
votes

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
1
What is Country2008E5? How is CountrySet1 used?dflemstr
I don't think you could write one by hand, let alone automatically generated; two different types that are both instances of Country could not be compared for equality.Louis Wasserman
The first thing to consider when you say "could this be derived" should be "how would I write this by hand?". If you can make mechanical rules for writing Eq instances then you can either use TH to deriving the instance or submit a patch to GHC. If you can't even write the instances manually, and I think Louis is right here, then you shouldn't expect some magic deriving extension to make things work.Thomas M. DuBuisson

1 Answers

1
votes

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.