그것이 생각하는 좋은 방법을 참조하십시오 "내가 아마도 값 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과 같은 함수를 사용하여 문자열을 수정하지 않는 한 문자열 리터럴을 안전하게 사용할 수 있습니다. 기본적으로 데이터 유형을 제자리에서 수정할 수있는 모든 기능은 부작용을 일으 킵니다.
스타일에 대한 하나의 힌트 : "if 표현, 그렇다면 참 거짓"패턴 또는 다른 유사한 패턴은 초보자들 사이에서 매우 일반적입니다. 생각해 보면 if 부분을 선택하려면 표현식이 참이어야하고 else 부분은 false 여야합니다. 따라서이 패턴을 삭제하고 "표현식"으로 줄일 수 있습니다. – LiKao
그 코드를 보여줄 수 있습니까? 나는 초심자이고 약간의 지침을 사용할 수있다. –
물론 간단합니다 : "if List.exists ((=) 7) myList then true true false ;;" "List.exists ((=) 7) myList ;;"라고 쓸 수 있습니다. 이유에 대해 생각해보기를 그만두면이 두 문장의 의미가 같은 이유가 무엇인지, 기능적 (및 일반적인) 프로그래밍에 대해 많은 것을 배우게됩니다. – LiKao