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
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:
? 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
.
CodePudding user response:
When you define a function named ( )
, you are shadowing Prelude's addition function. In the body of ( ) :: Day -> Int -> Day
, you evaluate (y 1)
, expecting an Int
. But this new ( )
function returns a Day
! The more polymorphic version for Enum
works, because Int
has an Enum
instance, and so ( )
can be used on both types.
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)
.