使用 Haskell 检查有效日期

Check A Valid Date using Haskell

我有这样的代码来检查日期是否有效

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)

但为什么 returns 解析错误:(

在Haskell中,if ...是一个表达式;它 必须 具有 else,这样即使不满足条件,if 表达式作为一个整体也会求值:

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

我想可以通过使用守卫和 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)