[英]A question of Type declaration in Haskell
I'm a new one And study from book:我是一个新人并从书中学习:
data Day = Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday deriving (Eq, Ord, Show, Read, Bounded, Enum)
I thought that I can write a func to use +, example: Monday + 1 = Tuesday我以为我可以写一个func来使用+,例如:Monday + 1 = Tuesday
So:所以:
:{
(+) :: Day -> Int -> Day
(+) x y
| y>0 = (+) (succ x) (y-1)
| y<0 = (+) (pred x) (y+1)
| y==0 = x
:}
But ghci said it has a mistake:但是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
I don't know why but I tried another one:我不知道为什么,但我尝试了另一个:
:{
(+) :: (Enum a) => a -> Int -> a
(+) x y
| y>0 = (+) (succ x) (y-1)
| y<0 = (+) (pred x) (y+1)
| y==0 = x
:}
It works well, like:它运作良好,例如:
ghci> Monday + 1
Tuesday
ghci> Monday + 3
Thursday
ghci> Thursday + (-2)
Tuesday
But I still don't know what's wrong with "Day -> Int -> Day"... Please help但是我仍然不知道“Day -> Int -> Day”有什么问题......请帮助
When you define a function named (+)
, you are shadowing Prelude's addition function.当您定义一个名为(+)
的 function 时,您将隐藏 Prelude 的添加 function。 In the body of (+):: Day -> Int -> Day
, you evaluate (y + 1)
, expecting an Int
.在(+):: Day -> Int -> Day
的正文中,您评估(y + 1)
,期待Int
。 But this new (+)
function returns a Day
!但是这个新的(+)
function 返回了Day
! The more polymorphic version for Enum
works, because Int
has an Enum
instance, and so (+)
can be used on both types. Enum
的多态版本有效,因为Int
有一个Enum
实例,因此(+)
可以用于两种类型。
To get around this, you could simply give this operation a new name instead of shadowing (+)
.为了解决这个问题,您可以简单地给这个操作一个新名称而不是阴影(+)
。 Or, you could be explicit in the recursive call when you want to use your new (+)
and when the original one, by writing (y Prelude.+ 1)
.或者,当您想使用新的(+)
时,您可以在递归调用中明确表示,而当您想使用原始调用时,可以通过编写(y Prelude.+ 1)
来明确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.