2014-03-06 2 views
0

OCaml/함수 프로그래밍에 익숙합니다. 비교적 간단한 다른 언어의 구현에 대해 혼란 스럽습니다. 나는 모든 도움을 사용할 수 있습니다.OCaml : 제어문을 사용하여 변수의 값을 유지하십시오.

주로 : 내가 작업하고있는 프로그램에서 특정 매개 변수를 기반으로 변수를 증가 또는 감소시킵니다. 여기에 내가 무엇을의 뭔가 담당자 : 그것은 아마도, 매번 인 것처럼 else 문이 촬영되지 않습니다 경우에도 때문에

let tot = ref 0 in 
for i = 0 to s do 
    if test_num > 0 then 
     tot := !tot + other_num 
    else 
     tot := !tot - other_num 
done;; 

이것은 분명히 그것에 대해 이동하는 방법이 아니다, 코드의 역할 프로그램의 바닥에 가깝기 때문에? 나는 OCaml이 꽤 정교한 패턴 일치를 가지고 있음을 알고 있지만,이 수준의 coed 내에서 나는 이미 만든리스트에 대한 접근이 필요하다. 그리고 내가 이해할 수있는 한, 최상위 레벨 함수에서 그리스트에 접근 할 수 없다. 매개 변수로 모두 전달하지 않아도됩니다.

나는 이것이 잘못된 방법 일 것이라는 것을 알고 있지만, 나는 이것을 어떻게 관용적으로하는지 잘 모른다.

제안 사항? 감사.

편집 다음은보다 간결 예제 : 나는 max_mem를 인쇄 할 때, 나는 19를 얻을 수 끝에

let ex_list = [1; -2; 3; -4] in 
let max_mem = ref 0 in 
let mem = ref 0 in 
let() = 
    for i = 0 to 3 do 
     let transition = List.nth ex_list i in 
     if transition > 0 then (
      mem := (!mem + 10); 
     ) else 
      mem := (!mem - 1); 
     if (!mem > !max_mem) then (max_mem := !mem); 
    done; 
print_int !max_mem; print_string "\n"; 
in !mem; 

는,이 값이해야하지만 (0 + 1 - 10 + 10-1 = 18). 수학을 잘못하고 있습니까, 아니면 문제가 다른 곳에서 왔습니까?

+0

! mem의 최대 값은 18입니다. 최종 값은 18입니다. 전혀 문제가 나타나지 않습니다. 루프 주변의 4 번 끝 부분의 값은 10, 9, 19, 18입니다. (측면 설명으로 이것이 질문의 본질이라면 이것은 훌륭한 예입니다.) –

답변

2

코드가 괜찮습니다. 실제 코드처럼 많은 의미를 갖지는 않지만 일반적인 레이아웃을 표시하려고하는 것 같습니다. 그것은 또한 명령형으로 쓰여졌습니다. 가능한 한 피하려고합니다.

OCaml의 if은 다른 언어에서와 마찬가지로 작동합니다. 프로그램 하단 근처에는 특별한 것이 없습니다. (보다 정확하게는 C 및 관련 언어의 ? : 삼항 연산자처럼 작동합니다. 즉 표현식입니다.)

코드가 유용한 값을 반환하지 않습니다. 항상 () ("단위"로 알려진 본질적으로 흥미로운 값)을 반환합니다. 우리가 상수하여 자유 변수 (코드의이 비트에 정의되지 않은 것)를 대체하고 값을 반환하는 코드를 변경하는 경우

, 우리는 그것을 실행할 수 있습니다

# let s = 8 in 
let other_num = 7 in 
let test_num = 3 in 
let tot = ref 0 in 
let() = 
    for i = 0 to s do 
     if test_num > 0 then 
      tot := !tot + other_num 
     else 
      tot := !tot - other_num 
    done 
in 
!tot;; 
- : int = 63 
# 

당신이하려는 경우 당신이 tot 매개 변수를 재귀 함수로이 루프를 작성 할 것 (가변 변수없이, 즉) 기능 스타일로 작성하는 학습 :

# let s = 8 in 
let other_num = 7 in 
let test_num = 3 in 
let rec loop n tot = 
    if n > s then 
     tot 
    else 
     let tot' = 
      if test_num > 0 then tot + other_num else tot - other_num 
     in 
     loop (n + 1) tot' 
in 
loop 0 0;; 
- : int = 63 

아마도 당신이 준 경우 도움이 쉬울 것 (추가 수정 : 작은 :-) 당신이 풀려고하는 자체 포함 된 문제.

질문의 다른 부분에 대한 조언이 충분하지 않습니다. 내가 지적 할 수있는 한 가지는 목록을 처리 할 때 패턴 일치를 사용하는 것이 완전히 관용적이라는 것입니다.

또한 매개 변수로 물건을 전달하는 데는 문제가 없습니다.이것이 언어가 "기능적"이라고 불리는 이유입니다. 코드는 매개 변수가있는 함수로 구성됩니다.

업데이트

나는 let() = expr1 in expr2 대신 expr1; expr2을 쓰는 것을 좋아합니다. 내가 습득 한 습관 일뿐입니다. 혼란 스럽다면 미안 해요. 본질은 부작용 (첫 번째 표현식은 unit)을 평가 한 다음 두 번째 표현식의 값을 반환한다는 것입니다.

for 뒤에 내용이없는 경우 코드는 ()으로 평가됩니다. 코드의 목적은 !tot의 값을 계산하는 것으로 보이기 때문에 이것이 내가 반환 한 것입니다. 적어도 OCaml 최상위 레벨에서 계산 된 값을 볼 수 있습니다.

tot'은 또 다른 변수입니다. var이라는 변수에서 새 값을 직접 계산하면 새 값 var'의 이름을 지정하는 것이 일반적입니다. 그것은 "var prime"로 읽습니다.

업데이트 2

귀하의 예제 코드 확인을 작동하지만, 그것은 느린 (차) 작업입니다 목록을 통과 할 List.nth을 사용하는 문제가있다. 실제로 코드는 자연스럽게 배제됩니다. 다음은 기능적인 스타일을 작성할 수 있습니다 방법은 다음과 같습니다

# let ex_list = [1; -2; 3; -4] in 
let process (tot, maxtot) transition = 
    let tot' = if transition > 0 then tot + 10 else tot - 1 in 
    (tot', max maxtot tot') 
in 
List.fold_left process (0, 0) ex_list;; 
- : int * int = (18, 19) 
# 
+0

감사합니다. 도움이됩니다. 간결함을 위해서 제 코드 전체를 포함시키지 않았지만 아래 주석에서 그렇게 할 것입니다. 당신의 대답과 관련해서, 나는 몇 가지 질문을한다 :'let() ='... 루프 전에, 그리고 그 뒤에'in! tot'은 무엇인가? 참조의 내용을 가져 오기 위해'! tot'을해야한다는 것을 알고 있지만, 결국 변수를 호출하기 위해 무엇을해야합니까? 또한, 당신의 재귀 함수에서'tot'과 반대로'tot'의 의미는 무엇입니까? – prichey

+0

(이 새로운 정보로 내 대답을 편집 할 예정이며, 앞뒤의 질문에 대해서는이 주석이 잘 작동하지 않습니다.) –

+0

또한 내 코드보다는 내 코드를 사용하여 답변을 편집했습니다. 정직한 실수. – prichey

0

제프리의 대답에 더하여, 둘째 날 수 있도록이가 매우 낮은 수준이 필수적이기 때문에 당신이 일반적으로, OCaml의 이러한 코드를 작성 얼마나 아니라고 접근. 보다 기능적인 버전은 다음과 같습니다 :

let high ex_list = 
    let deltas = List.map (fun x -> if x > 0 then 10 else -1) ex_list in 
    snd (List.fold_left (fun (n, hi) d -> (n+d, max (n+d) hi)) (0, 0) deltas) 

let test = high [1; -2; 3; -4] 
관련 문제