3

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
Ra is dead
  • 569
  • 2
  • 18
  • What is `Country2008E5`? How is `CountrySet1` used? – dflemstr Aug 06 '12 at 17:15
  • 4
    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 Aug 06 '12 at 17:23
  • 1
    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 Aug 06 '12 at 17:41

1 Answers1

2

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.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380