Reputation: 23
This is the piece of code that I am trying to understand
data Day = Mon | Tue | Wed | Thu | Fri | Sat | Sun
isWeekend :: Day -> Bool
isWeekend Sat = True
isWeekend Sun = True
isWeekend _ = False
isWeekday :: Day -> Bool
isWeekday = not.isWeekend
If I am trying to evaluate isWeekday Mon (I specified an argument of type Day from the function definition even if the actual function does not have it), it works. If I am modifying the isWeekday into isWeekday day, I have the following error: Couldn't match expected type Bool' with actual type
Day -> Bool'.
Could somebody please tell me why I have to skip the parameter which has the type Day?
Thank you!
Upvotes: 2
Views: 72
Reputation: 477190
the reason that not . isWeekend
has type Day -> Bool
is because not . isWeekend
will return a function. A key aspect of functional programming is that functions are "first class citizens": you can pass functions as parameters, and return functions.
Since (.)
has type (.) :: (b -> c) -> (a -> b) -> (a -> c)
, and not
has type not :: Bool -> Bool
, this means that not . isWeekend
, or more canonical (.) not isWeekend
thus has type:
(.) :: ( b -> c ) -> ( a -> c ) -> ( b -> c )
not :: Bool -> Bool
isWeekend :: Day -> Bool
--------------------------------------------------------
not . isWeekend :: Day -> Bool
This expression this will return a function that takes a Day
as parameter and returns a Bool
.
You can write a version of isWeekday
with a parameter:
isWeekday :: Day -> Bool
isWeekday day = not (isWeekend day)
But then you thus can not define this as , since then it means that isWeekday2 day = not . isWeekend
day
is a "useless" parameter, and it will still return a function, so then the signature is isWeekday2 :: a -> Day -> Bool
.
Upvotes: 4