sml - How to get a list of months by giving two days of a year? -
i have function named month_range
takes 2 days of year input (e.g., 65 , 128, assuming year has 365 days) , returns list number of month days day1 through day2 belongs to.
the size of list must "day2 - day1 + 1".
example : month_range(25,35) should return : [1,1,1,1,1,1,1,2,2,2,2]
i wrote following code
fun month_range (day1:int,day2:int) = let val month_days= [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; fun what_month(day :int) = let fun aux(sum :int, numbers: int list) = let val numbers_tail = tl numbers in if sum <= (hd numbers) 1 else 1 + aux(sum, (hd numbers + hd numbers_tail) :: (tl numbers_tail)) end in aux(day, month_days) end in if (day1>day2) [] else what_month(day1) @ what_month(day1 + 1)@::what_month(day2) end
but gives me following error
/tmp/emacs-region5156f3r:21.51-21.54 error: unbound variable or constructor: @:: /tmp/emacs-region5156f3r:21.12-21.70 error: operator not function [literal] operator: int in expression: (what_month (day1 + 1)) <errorvar> /tmp/emacs-region5156f3r:21.12-21.70 error: operator , operand don't agree [literal] operator domain: 'z list * 'z list operand: int * _ in expression: what_month day1 @ (((what_month <exp>) <errorvar>) what_month) day2 uncaught exception error raised at: ../compiler/toplevel/interact/evalloop.sml:66.19-66.27 ../compiler/toplevel/interact/evalloop.sml:44.55 ../compiler/toplevel/interact/evalloop.sml:296.17-296.20
first off can see error message, using @::
, doesn't make sense.
you have made function what_month
assignment, there no reason putting inside let-expression.
now if simplify code bit
val month_days= [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; fun what_month(day :int) = let fun aux(sum :int, numbers: int list) = let val numbers_tail = tl numbers in if sum <= (hd numbers) 1 else 1 + aux(sum, (hd numbers + hd numbers_tail)::(tl numbers_tail)) end in aux(day, month_days) end fun month_range (day1:int,day2:int) = if (day1>day2) [] else what_month(day1)
then see still doesn't type. because type of what_month
function int -> int
, if-expression inside body of month_range
returns list in branch, must return list in else branch. fix that.
currently function returns number of month day1 belongs (theoretically, doesn't type yet). wan't return list days day1 ... day2.
recursion comes in. if return what_month(day1)
concatenated recursive call month_range( day1 + 1, day2)
end building list
what_month(day1) :: what_month(day1 + 1) :: what_month(day1 + 1 + 1) ...
and since return empty list, when reach condition day1 > day2
, recursion give result this
what_month(day1) :: what_month(day1 + 1) :: what_month(day1 + 1 + 1) :: ... :: what_month(day2) ::[]
the resulting code looks this
fun month_range (day1:int,day2:int) = if (day1>day2) [] else what_month(day1) :: month_range(day1 + 1, day2) - month_range(25,35); val = [1,1,1,1,1,1,1,2,2,2,2] : int list
Comments
Post a Comment