Home > Enterprise >  Check A Valid Date using Haskell
Check A Valid Date using Haskell

Time:01-28

i have a code like this to check if a date is valid or not

isKabisat :: Int -> Bool

isDateValid :: Int -> Int -> Int -> Bool

isKabisat y = ((mod y 400)==0) || ((mod y 100 )/=0 && (mod y 4)==0)

isDateValid d m y = 
    if (y>=1900 && y<=1999) then 
        if (m==1) || (m==3) || (m==5) || (m==7) || (m==8) || (m==10) || (m==12) then
            (d>=1 && d<=31)
        else if (m==2) then
            (d>=1) && (d<=(if isKabisat y then 29 else 28))
        else if (m==4) || (m==6) || (m==9) || (m==11) then
            (d>=1) && (d<=30)

but why it returns parse error:(

CodePudding user response:

In Haskell, if ... is an expression; it must have else so that the if expression as a whole evaluates to something even when the condition is not satisfied:

module Main where

isKabisat :: Int -> Bool
isKabisat y = ((mod y 400)==0) || ((mod y 100 )/=0 && (mod y 4)==0)

isDateValid :: Int -> Int -> Int -> Bool
isDateValid d m y =
    if (y>=1900 && y<=1999) then
        if (m==1) || (m==3) || (m==5) || (m==7) || (m==8) || (m==10) || (m==12) then
            (d>=1 && d<=31)
        else if (m==2) then
            (d>=1) && (d<=(if isKabisat y then 29 else 28))
        else if (m==4) || (m==6) || (m==9) || (m==11) then
            (d>=1) && (d<=30)
        else False
    else False

main = do
  print $ isDateValid 26 1 1999 -- True
  print $ isDateValid 29 2 1999 -- False

I guess the code can be simplified by using a guard and elem:

isDateValid :: Int -> Int -> Int -> Bool
isDateValid d m y
  | y < 1900 || y > 1999 || d < 1  = False
  | m `elem` [1,3,5,7,8,10,12]     = d <= 31
  | m `elem` [4,6,9,11]            = d <= 30
  | m == 2                         = d <= if isLeapYear then 29 else 28
  | otherwise                      = False
  where isLeapYear = y `mod` 400 == 0 || (y `mod` 100 /= 0 && y `mod` 4 == 0)
  •  Tags:  
  • Related