Haskell中的类问题

huangapple go评论62阅读模式
英文:

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

你不需要在CycleColorSuit上使用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 不是声明CycleEq的有效语法。

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

huangapple
  • 本文由 发表于 2023年6月12日 14:19:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/76454029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定