parseDate :: Parser (Int, Int, Int)
parseDate = do
  t1 <- satisfyString isDigit; t2 <- satisfyString isDigit
  t3 <- satisfyString isDigit; t4 <- satisfyString isDigit
  _  <- satisfyString (== '-')
  t5 <- satisfyString isDigit; t6 <- satisfyString isDigit
  _  <- satisfyString (== '-')
  t7 <- satisfyString isDigit; t8 <- satisfyString isDigit
  let y = read (t1 ++ t2 ++ t3 ++ t4) :: Int
      m = read (t5 ++ t6) :: Int
      d = read (t7 ++ t8) :: Int
  if y < 0 then fail "Invalid year"
    else if m < 1 || m > 12 then fail "Invalid month"
         else if d < 1 || d > 31 then fail "Invalid day"
              else return (y, m, d)
parseDate :: Parser (Int, Int, Int)
parseDate = do
  t1 <- satisfyString isDigit; t2 <- satisfyString isDigit
  t3 <- satisfyString isDigit; t4 <- satisfyString isDigit
  _  <- satisfyString (== '-')
  t5 <- satisfyString isDigit; t6 <- satisfyString isDigit
  _  <- satisfyString (== '-')
  t7 <- satisfyString isDigit; t8 <- satisfyString isDigit
  let y = read (t1 ++ t2 ++ t3 ++ t4) :: Int
      m = read (t5 ++ t6) :: Int
      d = read (t7 ++ t8) :: Int
  if y < 0 then fail "Invalid year"
    else if m < 1 || m > 12 then fail "Invalid month"
         else if d < 1 || d > 31 then fail "Invalid day"
              else return (y, m, d)
parseDate = do
  t1 <- satisfyString isDigit; t2 <- satisfyString isDigit
  t3 <- satisfyString isDigit; t4 <- satisfyString isDigit
  _  <- satisfyString (== '-')
  t5 <- satisfyString isDigit; t6 <- satisfyString isDigit
  _  <- satisfyString (== '-')
  t7 <- satisfyString isDigit; t8 <- satisfyString isDigit
  let y = read (t1 ++ t2 ++ t3 ++ t4) :: Int
      m = read (t5 ++ t6) :: Int
      d = read (t7 ++ t8) :: Int
  if y < 0 then fail "Invalid year"
    else if m < 1 || m > 12 then fail "Invalid month"
         else if d < 1 || d > 31 then fail "Invalid day"
              else return (y, m, d)