如何为自定义数据类型定义 (+) 函数?
How to define (+) function for custom data type?
我是新人,正在学习书本:
data Day
= Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
deriving (Eq, Ord, Show, Read, Bounded, Enum)
我想我可以写一个 func 来使用 +,例如:星期一 + 1 = 星期二
所以:
:{
(+) :: Day -> Int -> Day
(+) x y
| y>0 = (+) (succ x) (y-1)
| y<0 = (+) (pred x) (y+1)
| y==0 = x
:}
但是ghci说它有错误:
? Couldn't match expected type ‘Int’ with actual type ‘Day’
? In the second argument of ‘(+)’, namely ‘(y + 1)’
In the expression: (+) (pred x) (y + 1)
In an equation for ‘+’:
(+) x y
| y > 0 = (+) (succ x) (y - 1)
| y < 0 = (+) (pred x) (y + 1)
| y == 0 = x
我不知道为什么,但我尝试了另一个:
:{
(+) :: (Enum a) => a -> Int -> a
(+) x y
| y>0 = (+) (succ x) (y-1)
| y<0 = (+) (pred x) (y+1)
| y==0 = x
:}
效果不错,比如:
ghci> Monday + 1
Tuesday
ghci> Monday + 3
Thursday
ghci> Thursday + (-2)
Tuesday
但是我还是不知道Day -> Int -> Day
有什么问题。
定义名为 (+)
的函数时,您正在隐藏 Prelude 的加法函数。在 (+) :: Day -> Int -> Day
的正文中,您计算 (y + 1)
,期望 Int
。但是这个新的(+)
函数returns一个Day
! Enum
的多态版本有效,因为 Int
有一个 Enum
实例,因此 (+)
可以用于两种类型。
要解决这个问题,您可以简单地为该操作指定一个新名称,而不是隐藏 (+)
。或者,当您想使用新的 (+)
和原始的 (y Prelude.+ 1)
.
时,您可以在递归调用中明确表示
我是新人,正在学习书本:
data Day
= Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
deriving (Eq, Ord, Show, Read, Bounded, Enum)
我想我可以写一个 func 来使用 +,例如:星期一 + 1 = 星期二
所以:
:{
(+) :: Day -> Int -> Day
(+) x y
| y>0 = (+) (succ x) (y-1)
| y<0 = (+) (pred x) (y+1)
| y==0 = x
:}
但是ghci说它有错误:
? Couldn't match expected type ‘Int’ with actual type ‘Day’
? In the second argument of ‘(+)’, namely ‘(y + 1)’
In the expression: (+) (pred x) (y + 1)
In an equation for ‘+’:
(+) x y
| y > 0 = (+) (succ x) (y - 1)
| y < 0 = (+) (pred x) (y + 1)
| y == 0 = x
我不知道为什么,但我尝试了另一个:
:{
(+) :: (Enum a) => a -> Int -> a
(+) x y
| y>0 = (+) (succ x) (y-1)
| y<0 = (+) (pred x) (y+1)
| y==0 = x
:}
效果不错,比如:
ghci> Monday + 1
Tuesday
ghci> Monday + 3
Thursday
ghci> Thursday + (-2)
Tuesday
但是我还是不知道Day -> Int -> Day
有什么问题。
定义名为 (+)
的函数时,您正在隐藏 Prelude 的加法函数。在 (+) :: Day -> Int -> Day
的正文中,您计算 (y + 1)
,期望 Int
。但是这个新的(+)
函数returns一个Day
! Enum
的多态版本有效,因为 Int
有一个 Enum
实例,因此 (+)
可以用于两种类型。
要解决这个问题,您可以简单地为该操作指定一个新名称,而不是隐藏 (+)
。或者,当您想使用新的 (+)
和原始的 (y Prelude.+ 1)
.