2011-10-10 3 views
5

OCaml의 괄호 :내가 OCaml로의 최상위 코드의 매우 간단한 조각을 평가하고

let p5() = print_int 5;; 
p5();; 

print_string "*************************";; 

let p4 = print_int 4;; 
p4;; 

을 그리고 그것은 반환

val p5 : unit -> unit = <fun> 
# 5- : unit =() 
# *************************- : unit =() 
# 4val p4 : unit =() 
# - : unit =() 

내 질문 ()은 평균 무엇

  1. 있습니다 let p5() = print_int 5;;에?
  2. -()# 5- : unit =()에서 무엇을 의미합니까?
  3. p4은 기능입니까?
  4. 의 시작 부분에 4이있는 이유는 무엇입니까?
  5. ()은 부작용을 숨기려면 Ocaml 코드에서 사용할 수있을 것 같습니다. 여기
+1

는'대신 print_string''의 print_endline'가 자동으로 endline 후를 출력하기 때문에 – newacct

답변

11

일부 답변 :

  1. ()는 유닛 타입 값이다. 단위 유형은 값이 하나 뿐인 유형입니다. 이것은 일반적으로 아무 의미가 없거나 의미가없는 함수를 생성하는 데 사용됩니다. OCaml에서 모든 함수는 항상 뭔가를 반환하고 몇 가지 인수를 취해야한다는 것을 기억하십시오. 따라서이 제한을 피하기 위해 단위 유형이 사용됩니다. 이 점을 C, C++ 또는 Java의 void 유형과 유사하게 생각하십시오.
  2. 인터리브 된 두 줄이 있습니다. 5은 최상위가 아닌 print_int 함수로 인쇄됩니다. 최고 레벨은 5없이 - : unit =()을 반환합니다. 최상위 요소는 새로운 바인딩 -을 생성하지 않았고 마지막으로 반환 된 값은 unit이고 값은 ()입니다.
  3. 아니요. 인수가 없으므로 함수가 아닙니다.
  4. 다시 두 줄이 삽입됩니다. 4print_int 기능으로 인쇄됩니다. 현재 최상위 레벨은 새로운 바인딩 p4을 생성했으며,이 변수는 unit 유형의 값을 가지며 저장된 값은 ()임을 나타냅니다.
  5. 아니요, ()은 부작용을 숨기지 않습니다. 일반적으로 부작용이있는 함수를 작성하는 데 사용되므로 어떤 종류의 인수도 필요하지 않습니다.
6

LiKao는 이미 모든 핵심 사항을 설명했지만, 한 번에 한 줄 씩 정의를 입력하면 어떤 입력이 어떤 응답에서 왔는지 보여줄 수 있습니다. 그 사람이 입력 한 라인은 #으로 시작합니다.

# let p5() = print_int 5;; 
val p5 : unit -> unit = <fun> 

이 유형 unit의 값을 받아들이고 형 unit의 값을 리턴하는 함수 (P5)을 정의한다. ()으로 작성된 유형 단위의 값은 하나뿐입니다. 그래서 이것들은 여러분이 요구하고있는 괄호입니다 (나는 생각합니다). 정의에 나타나는 ()은 함수에서 허용하는 값의 패턴입니다. 패턴으로, ()은 (패턴으로 사용 된 모든 상수처럼) 자체와 일치합니다.

# p5();; 
5- : unit =() 

이것은 다소 혼란 스럽습니다. 5p5 함수에 의해 작성되었습니다. 나머지는 OCaml 최상위 레벨의 응답입니다. 표현식의 결과는 unit이고 값은 ()입니다. 의미가 있습니다. print_intint -> unit입니다.

# print_string "*************************";; 
*************************- : unit =() 

여기에도 비슷한 혼란이 있습니다. 별표 *print_string로 작성되었습니다. 나머지는 결과를 나타내며 다시 값을 갖는 unit 유형입니다.

# let p4 = print_int 4;; 
4val p4 : unit =() 

같은 것이 있습니다. 4print_int로 작성되었습니다. 나머지는 최상위 레벨이 p4 인 기호가 unit이고 값이 () 인 기호를 정의했음을 보여줍니다. 다시 말하지만 이 unit 유형을 반환하고 ()이 해당 유형의 유일한 값이기 때문에 이는 의미가 있습니다. p4 유형에서 이 아니라이라는 기능을 알 수 있습니다. 함수에는 해당 유형에 화살표 (->)가 있습니다. p4은 단지 unit 유형의 값입니다.

# p4;; 
- : unit =() 

은 여기 유형과 p4의 값에 대한 최상위에게, 그리고 p4 유형 unit이며 값 ()을 가지고 (다시)을 알려줍니다.

2

마지막 질문은 "부작용 숨기기"에 ()이 어떻게 사용되는지입니다. 함수의 지연된 평가를 언급 한 것일 수 있습니다.

let p x = print_string "abc";; 
let q = print_string "abc";; 

pq간에 중요한 차이가있다 : 다음의 예이다. 차이점은 p이 유형이 'a -> unit이고 q이 유형이 unit 인 것입니다. p을 정의하면 아무 것도 인쇄되지 않습니다. 문자열 "abc"는 p 함수를 인수에 적용 할 때, 즉 p 1 또는 p "blah" 등을 평가할 때만 인쇄됩니다. 함수 p은 모든 유형의 인수를 사용하고 무시합니다. 따라서 p의 경우 함수 내에 "부작용이 숨겨져 있습니다".

"x"가 전혀 사용되지 않으므로 "p x"의 정의에 "x"라는 인수가있는 것은 의미가 없습니다. 따라서 단순화하기 위해 "단위"유형이 사용되므로 "p"의 정의는 "let p() = ..."와 같이 보입니다.

let p = fun() -> print_string "abc";; 

"p"는 "p()"로 사용됩니다. 이것은 C, Java 등의 프로그래밍 언어를 처음 배우면 혼란 스러울 수 있습니다. 여기서()는 모든 함수의 인수로 사용됩니다. 그러나 OCAML에서 ()은 "빈 값"을 나타내는 특수 기호이며이 값은 "단위"라는 특수 유형이 있습니다.()이 결과 값이기 때문에,이 "print_string을"평가의 부작용이기 때문에 문자열 "ABC"는, 바로 인쇄 및 q() 동일하게 : 당신이 q 정의로

완전히 다른 일이 일어난다 "print_string"을 평가하여 얻은 결과입니다.

0

내가 늦게 파티에,하지만 나는

let p5() = print_int 5 

()를 사용하는 것을 지적 할 p5의 인수에 일치하는 패턴을 가지고 있습니다.

let p5 x = match x with() -> print_int 5 

또는이 : 그것은이의 것과 동일

let p5 = function() -> print_int 5 

심지어이 :

let p5 = fun x -> match x with() -> print_int 5 

이러한 구분은 다음 코드에서 중요하다

let f (x, y) = print_int (x + y) 
let g x y = print_int (x + y) 

f 만 받음 하나의 매개 변수 (쌍 (x, y))이고 g은 두 개의 매개 변수를받습니다. f(int * int) -> unit 유형이고 g 유형은 int -> int -> unit입니다. 그래서 f은 다음과 같이 작성할 수 있습니다 :

let f pair = match pair with (x, y) -> print_int (x + y) 
사용에 익숙해 할 수 있습니다
관련 문제