Background
This problem comes courtesy of the great folks over at Exercism, and is a great way to start testing your Haskell knowledge once you’ve learned the basics of: Getting Started & Haskell functions.
Authors Note ✏️
This is the first problem I’ve tried to solve in Haskell after learning the basics via Learn You a Haskell and it’s the first problem on the list of exercises in Exercism–labelled “easy”. As a beginner, it did not go well and took much longer than I expected to solve…
The Problem
A leap year (in the Gregorian calendar) occurs:
- In every year that is evenly divisible by 4.
- Unless the year is evenly divisible by 100, in which case it’s only a leap year if the year is also evenly divisible by 400.
Some examples:
- 1997 was not a leap year as it’s not divisible by 4.
- 1900 was not a leap year as it’s not divisible by 400.
- 2000 was a leap year!
Knowledge You Need to Solve This Problem
- Basic Functions and How to Write Them
- The ‘mod’ Arithmetic Operator
- Guards or if-else statements
- Pattern Matching
The Solution
To solve this problem in Haskell, we need to create a function that checks whether a given year is a leap year based on the rules provided.
Leap Year Rules Recap
- A year is a leap year if it is divisible by 4.
- However, if the year is divisible by 100, it is not a leap year unless it is also divisible by 400.
A Haskell Solution
We can use guards to implement this function in a readable way. Here’s one way to solve this problem:
isLeapYear :: Int -> Bool
isLeapYear year
| year `mod` 400 == 0 = True
| year `mod` 100 == 0 = False
| year `mod` 4 == 0 = True
| otherwise = False
Explanation
- First guard: If
year
is divisible by 400, it is a leap year, so we returnTrue
. - Second guard: If
year
is divisible by 100 but not by 400, it is not a leap year, so we returnFalse
. - Third guard: If
year
is divisible by 4 (and not by 100), it is a leap year, so we returnTrue
. - Otherwise: If none of the above conditions are met, it is not a leap year.
Example Usage
isLeapYear 1997 -- Result: False
isLeapYear 1900 -- Result: False
isLeapYear 2000 -- Result: True
This function evaluates each condition in sequence, making it efficient and easy to understand. Each rule is checked in the correct order, ensuring that we handle the exceptions (divisibility by 100 and 400) properly.
💡 Helpful References
Exercism - Haskell Exercises on Exercism
https://exercism.org/tracks/haskell/exercises/leap
YouTube - 10 Ways to solve Leap on Exercism
https://www.youtube.com/watch?v=Fj5m16is5hI
Leave a Reply