HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Idiomatic Leap years in haskell

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
leapidiomatichaskellyears

Problem

I wrote a simple function to determine if a year is a leap year or not. It works, but does not feel idiomatic.

isLeapYear :: Int -> Bool
isLeapYear year =
    (mod year 400) == 0 || ((mod year 4) == 0 && not ((mod year 100) == 0))


Is there a more "haskelly" way to write this function ?

Solution

One thing that always comes to my mind when seeing code like that is one of the first principles in programming that everyone learns.

Don't repeat yourself.

In your code, the part that stands out is mod year n == 0; let's get away with it first:

isLeapYear :: Int -> Bool
isLeapYear year = divisibleBy 400 || (divisibleBy 4 && not $ divisibleBy 100)
    where
        divisibleBy x = mod year x


Using such short helpers is very convenient in Haskell. In my opinion it's one of the most important reasons for the code staying readable (contrary to some newcomers' opinions who just pile up code in one giant expression).

Now, what I don't like here is the full name for the year; I know, I know, it's descriptive, but bear with me:

type Year = Int

isLeapYear :: Year -> Bool
isLeapYear y = divisibleBy 400 || (divisibleBy 4 && not (divisibleBy 100))
    where
        divisibleBy x = mod y x == 0


Now, this is the point where I'd really, really leave it be.

Code Snippets

isLeapYear :: Int -> Bool
isLeapYear year = divisibleBy 400 || (divisibleBy 4 && not $ divisibleBy 100)
    where
        divisibleBy x = mod year x
type Year = Int

isLeapYear :: Year -> Bool
isLeapYear y = divisibleBy 400 || (divisibleBy 4 && not (divisibleBy 100))
    where
        divisibleBy x = mod y x == 0

Context

StackExchange Code Review Q#125749, answer score: 3

Revisions (0)

No revisions yet.