JoshuaMoore
JoshuaMoore

Reputation: 23

why sometimes a function that has parameters inside its definition but in the actual function does not have any?

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

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

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 isWeekday2 day = not . isWeekend, since then it means that day is a "useless" parameter, and it will still return a function, so then the signature is isWeekday2 :: a -> Day -> Bool.

Upvotes: 4

Related Questions