英文:
Class problems with Haskell
问题
这次,我有以下这些定义:
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
我的问题是这行代码:
class Eq a => Eq (Cycle a) where
产生了错误:
Unexpected type `Cycle a'
In the class declaration for `Eq'
A class declaration should have form
  class Eq a where ...
问:我在这里做错了什么?
英文:
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?
答案1
得分: 5
你不需要在Cycle、Color和Suit上使用Eq约束。你可以像这样编写模块:
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
英文:
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
答案2
得分: 3
首先,使用以下代码声明Cycle。这将声明带有Eq约束的Cycle类型类。class Eq a => Eq (Cycle a) where 不是声明Cycle或Eq的有效语法。
class Eq a => Cycle a where
  ...
然后,使用以下代码声明其实例。你不能写成Eq Color =>,因为Color是一个刚性类型。如果你尝试将其声明为Cycle的实例而Color不是Eq的实例,编译器会报错。
instance Cycle Color where
  ...
最终的代码将如下所示。
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
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论