diff --git a/sml/week1/date.sml b/sml/week1/date.sml index 64d4634..c9cd278 100644 --- a/sml/week1/date.sml +++ b/sml/week1/date.sml @@ -8,12 +8,30 @@ infix |> fun fold f lst acc = case lst of [] => acc - | head::tail => fold f tail (f head acc) + | head :: tail => fold f tail (f head acc) -fun is_older ( - (y1, m1, d1): Date, - (y2, m2, d2): Date -): bool = +fun reverse lst = + fold (fn elm => fn acc => elm :: acc) lst [] + + +(* non tail optimized :( *) +(* fun filter predicate lst = + case lst of + [] => lst + | head :: tail => + if predicate head + then head :: filter predicate tail + else filter predicate tail *) + +fun filter predicate lst = + let + val reversed = reverse lst + fun f elm acc = if predicate elm then elm :: acc else acc + in + fold f reversed [] + end + +fun is_older ((y1, m1, d1): Date, (y2, m2, d2): Date): bool = let val same_dates = y1 = y2 andalso m1 = m2 andalso d1 = d2 val older = y1 <= y2 andalso m1 <= m2 andalso d1 <= d2 @@ -21,10 +39,7 @@ fun is_older ( if same_dates then false else older end -fun number_in_month ( - dates: Date list, - month_to_find: int -): int = +fun number_in_month (dates: Date list, month_to_find: int): int = let fun count_month (_, month, _) occurences = if month = month_to_find @@ -34,13 +49,17 @@ fun number_in_month ( fold count_month dates 0 end -fun number_in_months ( - dates: Date list, - months_to_find: int list -): int = +fun number_in_months (dates: Date list, months_to_find: int list): int = let - fun count_months month acc = acc + number_in_month (dates, month) + fun count_months month acc = + acc + number_in_month (dates, month) in fold count_months months_to_find 0 end +fun dates_in_month (dates: Date list, in_month: int): Date list = + let + fun filter_dates (_, month, _) = in_month = month + in + filter filter_dates dates + end \ No newline at end of file diff --git a/sml/week1/date_tests.sml b/sml/week1/date_tests.sml index 4a6de89..175798e 100644 --- a/sml/week1/date_tests.sml +++ b/sml/week1/date_tests.sml @@ -97,4 +97,26 @@ val () = "number_in_months: multiple dates with same month" end +val () = + let + val dates = [] + val month = 12 + val expect = [] + in + assert + (dates_in_month (dates, month) = expect) + "dates_in_month: returns empty list on empty dates" + end + +val () = + let + val dates = [(2000, 11, 31), (2000, 12, 30), (2000, 12, 31)] + val month = 12 + val expect = [(2000, 12, 30), (2000, 12, 31)] + in + assert + (dates_in_month (dates, month) = expect) + "dates_in_month: filter non matching dates" + end + val () = complete () \ No newline at end of file