-1

Given a date between 2010 and 2019, the function is supposed to return an int 0 though 6 corresponding to Sunday through Saturday. The function is based on the fact that January 1, 2010 was a Friday.

Why does the else statement toward the end else if year = 2019 elicit the error for its entire body: "This expression has type int but an expression was expected of type unit"?

let day_of_week (year: int) (month: int) (day: int): int =
  if year < 2010 || year > 2019 then failwith "year out of range"
    else if month < 1 || month > 12 then failwith "invalid month"
    else if day < 1 then failwith "invalid day"
    else if is_leap_year year != true then (
            if month = 2 then (
                    if day > 28 then failwith "invalid day"
            )
    ) else if month = 2 then
            if day > 29 then failwith "invalid day"
    else if month = 4 || month = 6 || month = 9 || month = 11 then
            if day > 30 then failwith "invalid day"
    else if day > 31 then failwith "invalid day"
    else if year = 2010 then (
            if month = 1 then ((day mod 7) + 4) mod 7
            else if month = 2 then (((31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((304 + day) mod 7) + 4) mod 7
            else (((334 + day) mod 7) + 4) mod 7
    ) else if year = 2011 then (
            if month = 1 then (((365 + day) mod 7) + 4) mod 7
            else if month = 2 then (((365 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((365 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((365 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((365 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((365 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((365 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((365 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((365 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((365 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((365 + 304 + day) mod 7) + 4) mod 7
            else (((365 + 334 + day) mod 7) + 4) mod 7
    ) else if year = 2012 then (
            if month = 1 then (((730 + day) mod 7) + 4) mod 7
            else if month = 2 then (((730 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((730 + 60 + day) mod 7) + 4) mod 7
            else if month = 4 then (((730 + 91 + day) mod 7) + 4) mod 7
            else if month = 5 then (((730 + 121 + day) mod 7) + 4) mod 7
            else if month = 6 then (((730 + 152 + day) mod 7) + 4) mod 7
            else if month = 7 then (((730 + 182 + day) mod 7) + 4) mod 7
            else if month = 8 then (((730 + 213 + day) mod 7) + 4) mod 7
            else if month = 9 then (((730 + 244 + day) mod 7) + 4) mod 7
            else if month = 10 then (((730 + 274 + day) mod 7) + 4) mod 7
            else if month = 11 then (((730 + 305 + day) mod 7) + 4) mod 7
            else (((730 + 335 + day) mod 7) + 4) mod 7
    ) else if year = 2013 then (
            if month = 1 then (((1096 + day) mod 7) + 4) mod 7
            else if month = 2 then (((1096 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((1096 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((1096 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((1096 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((1096 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((1096 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((1096 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((1096 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((1096 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((1096 + 304 + day) mod 7) + 4) mod 7
            else (((1096 + 334 + day) mod 7) + 4) mod 7
    ) else if year = 2014 then (
            if month = 1 then (((1461 + day) mod 7) + 4) mod 7
            else if month = 2 then (((1461 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((1461 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((1461 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((1461 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((1461 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((1461 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((1461 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((1461 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((1461 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((1461 + 304 + day) mod 7) + 4) mod 7
            else (((1461 + 334 + day) mod 7) + 4) mod 7
    ) else if year = 2015 then (
            if month = 1 then (((1826 + day) mod 7) + 4) mod 7
            else if month = 2 then (((1826 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((1826 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((1826 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((1826 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((1826 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((1826 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((1826 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((1826 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((1826 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((1826 + 304 + day) mod 7) + 4) mod 7
            else (((1826 + 334 + day) mod 7) + 4) mod 7
    ) else if year = 2016 then (
            if month = 1 then (((2191 + day) mod 7) + 4) mod 7
            else if month = 2 then (((2191 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((2191 + 60 + day) mod 7) + 4) mod 7
            else if month = 4 then (((2191 + 91 + day) mod 7) + 4) mod 7
            else if month = 5 then (((2191 + 121 + day) mod 7) + 4) mod 7
            else if month = 6 then (((2191 + 152 + day) mod 7) + 4) mod 7
            else if month = 7 then (((2191 + 182 + day) mod 7) + 4) mod 7
            else if month = 8 then (((2191 + 213 + day) mod 7) + 4) mod 7
            else if month = 9 then (((2191 + 244 + day) mod 7) + 4) mod 7
            else if month = 10 then (((2191 + 274 + day) mod 7) + 4) mod 7
            else if month = 11 then (((2191 + 305 + day) mod 7) + 4) mod 7
            else (((2191 + 335 + day) mod 7) + 4) mod 7
    ) else if year = 2017 then (
            if month = 1 then (((2557 + day) mod 7) + 4) mod 7
            else if month = 2 then (((2557 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((2557 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((2557 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((2557 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((2557 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((2557 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((2557 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((2557 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((2557 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((2557 + 304 + day) mod 7) + 4) mod 7
            else (((2557 + 334 + day) mod 7) + 4) mod 7
    ) else if year = 2018 then (
            if month = 1 then (((2922 + day) mod 7) + 4) mod 7
            else if month = 2 then (((2922 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((2922 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((2922 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((2922 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((2922 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((2922 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((2922 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((2922 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((2922 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((2922 + 304 + day) mod 7) + 4) mod 7
            else (((2922 + 334 + day) mod 7) + 4) mod 7
    ) else if year = 2019 then (
            if month = 1 then (((3287 + day) mod 7) + 4) mod 7
            else if month = 2 then (((3287 + 31 + day) mod 7) + 4) mod 7
            else if month = 3 then (((3287 + 59 + day) mod 7) + 4) mod 7
            else if month = 4 then (((3287 + 90 + day) mod 7) + 4) mod 7
            else if month = 5 then (((3287 + 120 + day) mod 7) + 4) mod 7
            else if month = 6 then (((3287 + 151 + day) mod 7) + 4) mod 7
            else if month = 7 then (((3287 + 181 + day) mod 7) + 4) mod 7
            else if month = 8 then (((3287 + 212 + day) mod 7) + 4) mod 7
            else if month = 9 then (((3287 + 243 + day) mod 7) + 4) mod 7
            else if month = 10 then (((3287 + 273 + day) mod 7) + 4) mod 7
            else if month = 11 then (((3287 + 304 + day) mod 7) + 4) mod 7
            else (((3287 + 334 + day) mod 7) + 4) mod 7
    )
4

1 回答 1

3

我相信你的问题是这一行:

if day > 28 then failwith "invalid day"

没有else部分。缺少 else 部分等同于(),这会导致打字问题。

事实上编译器是对的。在我看来,这段代码实际上会在 2 月 29 日以外的日子里为非闰年返回 ()。

一种可能的解决方法是将代码部分更改为:

else if is_leap_year year != true && month = 2 && day > 28 then failwith "invalid day"
else . . .

作为旁注,在我看来is_leap_year != true更清楚地表达了。not is_leap_year

(作为另一边评论,Jeff Mercado 是正确的。你永远不会在实际项目中编写这样的代码。有很多方法可以做得更好。)

于 2013-07-16T04:48:31.020 回答