2011-09-28 2 views
8

숙제를 위해 우리는 "부작용"없이 업무를 완료하도록 지시 받았습니다. 위키 피 디아에서 "부작용"을 찾아 보았습니다. 이론적으로 "상태를 변경하거나 함수 호출과 관찰 가능한 상호 작용이 있음"을 의미하지만, 문제를 파악하는 데 문제가 있습니다.OCaml : 나중에 사용할 값을 저장하면 "부작용"이 발생합니까?

예를 들어 비 컴파일 시간 결과를 보유하는 값을 생성하면 부작용이 발생합니까?

은 (문법적으로 완벽하지 않을 수 있습니다) 내가 가진 말 :

val myList = (someFunction x y);; 
if List.exists ((=) 7) myList then true else false;; 

이이 부작용을 소개시겠습니까? 아마도 "부작용"의 정의에서 "상태를 변경하는"것에 혼란 스러울 지 모르겠습니다.

+3

스타일에 대한 하나의 힌트 : "if 표현, 그렇다면 참 거짓"패턴 또는 다른 유사한 패턴은 초보자들 사이에서 매우 일반적입니다. 생각해 보면 if 부분을 선택하려면 표현식이 참이어야하고 else 부분은 false 여야합니다. 따라서이 패턴을 삭제하고 "표현식"으로 줄일 수 있습니다. – LiKao

+0

그 코드를 보여줄 수 있습니까? 나는 초심자이고 약간의 지침을 사용할 수있다. –

+0

물론 간단합니다 : "if List.exists ((=) 7) myList then true true false ;;" "List.exists ((=) 7) myList ;;"라고 쓸 수 있습니다. 이유에 대해 생각해보기를 그만두면이 두 문장의 의미가 같은 이유가 무엇인지, 기능적 (및 일반적인) 프로그래밍에 대해 많은 것을 배우게됩니다. – LiKao

답변

8

아니오; 부작용은 예를 들어. 할당 연산자 :=을 사용하여 셀을 ref으로 변경하거나 이름이 참조하는 값이 시간이 지남에 따라 변경되는 기타 작업. 이 경우 myList은 프로그램 중에 변경되지 않는 불변 값이므로 효과가 없습니다.

http://en.wikipedia.org/wiki/Referential_transparency_(computer_science)

+0

감사합니다.이 링크는 기능 프로그래밍과 부작용을 이해하는 데 매우 유용합니다. –

5

그것이 생각하는 좋은 방법을 참조하십시오 "내가 아마도 값 I 이외 볼 수 이후 코드 (나중에 다시이 같은 기능을 실행 포함) 아무것도 변경 돌아 오는거야? 그렇다면 그것은 부작용입니다. 그렇지 않다면, 당신은 하나가 없다는 것을 알 수 있습니다.

그래서, 뭔가 같은 :

let inc_nosf v = v+1 

은 부작용이없는 그냥 정수 V 이상의 더 새로운 값을 반환하기 때문에 당신은 OCaml의 최상위에 다음 코드를 실행하면, 당신이 얻을 그래서. 해당 결과 :

# let x = 5;; 
val x : int = 5 
# inc_nosf x;; 
- : int = 6 
# x;; 
- : int = 5 

x의 값은 변경되지 않았습니다. 따라서 반환 값을 저장하지 않았으므로 아무 것도 실제로 증가하지 않습니다. 함수 자체는 x 자체가 아닌 반환 값을 수정합니다. inc_nosf 기능이 아닌 다른를함으로써 부작용 (즉, 그것은 단지 그것의 반환 값을 사용하여 외부 세계와 통신입니다 없습니다

# let x = inc_nosf x;; 
val x : int = 6 
# x;; 
- : int = 6 

이후 : 그래서 X에 저장하기 위해, 우리는해야 할 것 변경).

그러나 어떤 같은 그 R로 표시되는 기준에 저장된 값을 변경하기 때문에

let inc_sf r = r := !r+1 

부작용을 갖는다. 당신은 최상위 레벨에서 유사한 코드를 실행한다면, 당신은 대신,이 얻을 :

# let y = ref 5;; 
val y : int ref = {contents = 5} 
# inc_sf y;; 
- : unit =() 
# y;; 
- : int ref = {contents = 6} 

그래서,이 경우, 우리는 여전히 반환 값을 저장하지 않더라도, 어쨌든 증가되었다. 즉 반환 값 이외의 값이 변경되었을 것임을 의미합니다. 이 경우, 그 변경은 ref의 저장된 값을 변경 한 :=을 사용한 할당이었습니다.

Ocaml에서 ref, 레코드, 클래스, 문자열, 배열 및 해시 테이블을 사용하지 않는 경우 부작용 위험을 피할 수 있습니다. String.set 또는 String.fill과 같은 함수를 사용하여 문자열을 수정하지 않는 한 문자열 리터럴을 안전하게 사용할 수 있습니다. 기본적으로 데이터 유형을 제자리에서 수정할 수있는 모든 기능은 부작용을 일으 킵니다.

관련 문제