programming_languages/sml/week1/date.sml

65 lines
1.6 KiB
Standard ML
Raw Normal View History

2020-05-31 18:35:01 +03:00
(* year * month * day *)
type Date = int * int * int
2020-06-01 01:55:44 +03:00
fun |> (x, f) = f x
infix |>
2020-05-31 18:35:01 +03:00
fun fold f lst acc =
case lst of
[] => acc
2020-06-01 15:05:24 +03:00
| head :: tail => fold f tail (f head acc)
2020-05-31 18:35:01 +03:00
2020-06-01 15:05:24 +03:00
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 =
2020-05-31 18:35:01 +03:00
let
val same_dates = y1 = y2 andalso m1 = m2 andalso d1 = d2
val older = y1 <= y2 andalso m1 <= m2 andalso d1 <= d2
in
if same_dates then false else older
end
2020-06-01 15:05:24 +03:00
fun number_in_month (dates: Date list, month_to_find: int): int =
2020-05-31 18:35:01 +03:00
let
fun count_month (_, month, _) occurences =
if month = month_to_find
then occurences + 1
else occurences
in
fold count_month dates 0
end
2020-06-01 15:05:24 +03:00
fun number_in_months (dates: Date list, months_to_find: int list): int =
2020-06-01 01:55:44 +03:00
let
2020-06-01 15:05:24 +03:00
fun count_months month acc =
acc + number_in_month (dates, month)
2020-06-01 01:55:44 +03:00
in
fold count_months months_to_find 0
end
2020-06-01 15:05:24 +03:00
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