Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class problems with Haskell

This time, I have these definitions:

data Color = Red | Green | Blue
  deriving (Show, Eq)

data Suit = Club | Spade | Diamond | Heart
  deriving (Show, Eq)

class Eq a => Eq (Cycle a) where
  step :: a -> a
  stepMany :: Integer -> a -> a
  stepMany 0 x = x
  stepMany steps x = stepMany (steps - 1) (step x)
    
instance Eq Color => Cycle Color where
  step color
    | color == Red = Green
    | color == Green = Blue
    | color == Blue = Red

instance Eq Suit => Cycle Suit where
  step suit 
    | suit == Club = Spade
    | suit == Spade = Diamond
    | suit == Diamond = Heart
    | suit == Heart = Club

My problem is that the line

class Eq a => Eq (Cycle a) where'='"

produces the error

    Unexpected type `Cycle a'
    In the class declaration for `Eq'
    A class declaration should have form
      class Eq a where ...
  |
7 | class Eq a => Eq (Cycle a) where
  |

Q: What am I doing wrong here?

like image 301
coderodde Avatar asked Apr 10 '26 18:04

coderodde


2 Answers

You don't need the Eq constraint on Cycle, nor on Color and Suit. You can just write the module like this:

data Color = Red | Green | Blue
  deriving (Show, Eq)

data Suit = Club | Spade | Diamond | Heart
  deriving (Show, Eq)

class Cycle a where
  step :: a -> a
  stepMany :: Integer -> a -> a
  stepMany 0 x = x
  stepMany steps x = stepMany (steps - 1) (step x)

instance Cycle Color where
  step color
    | color == Red = Green
    | color == Green = Blue
    | color == Blue = Red

instance Cycle Suit where
  step suit 
    | suit == Club = Spade
    | suit == Spade = Diamond
    | suit == Diamond = Heart
    | suit == Heart = Club
like image 93
Mark Seemann Avatar answered Apr 13 '26 22:04

Mark Seemann


First, use this to declare Cycle. This declares Cycle type class with Eq constraint. class Eq a => Eq (Cycle a) where isn't a valid syntax to declare neither Cycle nor Eq.

class Eq a => Cycle a where
  ...

Then, use this to declare its instance. You cannot write Eq Color => because Color is a rigid type. The compiler will make it an error if Color isn't an instance of Eq while you try to make it an instance of Cycle.

instance Cycle Color where
  ...

The final code will be like this.

data Color = Red | Green | Blue
  deriving (Show, Eq)

data Suit = Club | Spade | Diamond | Heart
  deriving (Show, Eq)

class Eq a => Cycle a where
  step :: a -> a
  stepMany :: Integer -> a -> a
  stepMany 0 x = x
  stepMany steps x = stepMany (steps - 1) (step x)

instance Cycle Color where
  step color
    | color == Red = Green
    | color == Green = Blue
    | color == Blue = Red

instance Cycle Suit where
  step suit
    | suit == Club = Spade
    | suit == Spade = Diamond
    | suit == Diamond = Heart
    | suit == Heart = Club
like image 22
snak Avatar answered Apr 13 '26 21:04

snak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!