2013-04-05 1 views
-1

나는 일년의 이틀을 입력으로 받아들이는 함수 (예 : 65와 128, 연도가 365 일이라고 가정)를 가지고 day1에서 day2까지의 날이 속한 월의 수를 가진 목록을 반환하는 month_range 함수가있다. .일년의 이틀을 제공하여 월 목록을 얻는 방법?

목록의 크기는 "day2 - day1 + 1"이어야합니다.

예 : month_range (25, 35)를 반환해야합니다 : [1,1,1,1,1,1,1,2,2,2,2]

나는 다음과 같은 코드를 작성

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) 
        then 1 
        else 
        1 + aux(sum, (hd numbers + hd numbers_tail) 
          :: (tl numbers_tail)) 
       end 
      in 
      aux(day, month_days) 
      end 
    in 
     if (day1>day2) 
     then [] 
     else what_month(day1) @ what_month(day1 + 1)@::what_month(day2) 
    end 

하지만 정말 이해가되지 않는, @::를 사용하고 있는지, 나에게 오류 메시지에서 볼 수있는 다음과 같은 오류

/tmp/emacs-region5156f3r:21.51-21.54 Error: unbound variable or constructor: @:: 
/tmp/emacs-region5156f3r:21.12-21.70 Error: operator is not a function [literal] 
    operator: int 
    in expression: 
    (what_month (day1 + 1)) <errorvar> 
/tmp/emacs-region5156f3r:21.12-21.70 Error: operator and 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 
+0

추가 할 때 코드를 형식화하고 항상 오류 메시지도 넣으십시오. –

+0

OK, Jes ... 내가 할께. – Olivia

답변

2

첫째을 제공합니다.

대부분의 경우 다른 할당을 위해 what_month 함수를 만들었으므로 let-expression 안에 넣을 이유가 없습니다.

이제 우리는 당신의 코드를 단순화하면 조금

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) 
      then 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) 
     then [] 
     else what_month(day1) 

는 우리는 아직 입력하지 않는 것을 볼 수 있습니다. 이는 what_month 함수의 유형이 int -> int이기 때문에 month_range 본문의 if식이 then 분기의 목록을 반환하면 else 분기의 목록도 반환해야합니다. 우리가 고칠 것입니다.

현재이 함수는 day1이 속한 월의 숫자 만 반환합니다 (이론적으로 아직 입력하지 않았으므로). 우리는 모든 날 day1 ... day2에 대한 목록을 반환하지 않을 것입니다. 재귀가 들어오는 곳
이입니다. 우리가 month_range(day1 + 1, day2)에 재귀 호출로 연결된 what_month(day1)를 반환 할 경우, 우리는 목록을

what_month(day1) :: what_month(day1 + 1) :: what_month(day1 + 1 + 1) ... 

을 구축 끝날 당신은 빈 목록을 반환하기 때문에이 조건에 도달하면 day1 > day2 재귀는 당신에게 결과 코드는이

fun month_range (day1:int,day2:int) = 
    if (day1>day2) 
    then [] 
    else what_month(day1) :: month_range(day1 + 1, day2) 

- month_range(25,35); 
val it = [1,1,1,1,1,1,1,2,2,2,2] : int list 
처럼 보이는이

what_month(day1) :: what_month(day1 + 1) :: what_month(day1 + 1 + 1) :: ... 
       :: what_month(day2) ::[] 

같은 결과를 줄 것이다

+0

작동합니다. Jesper, 정말 고마워요. – Olivia