[PL] OCaml Basic
👑 OCaml Basic
💡 주석 (Comment)
OCaml은 여러줄 주석만 지원한다.
(* This is multiline comment *)
💡 Standard I/O
-
기본 입력
read_line()함수 : 사용자 입력을 문자열로 반환한다.unit타입, 즉 인자가 없으며, return 타입은string이다.- 한 줄 전체를
string으로 반환하는데,\n (linefeed)는 제외한다.
-
기본 출력
Format모듈을 사용한printfFormat모듈은 다양한 형태의 함수를 지원한다.- 그 중
printf는 formatted string을 출력해준다.
let name = "OCaml" in let age = 25 in Format.printf "Name : %s, Age : %d\n" name, age
💡 변수 (Variable)
OCaml에서 변수는 특정 값에 묶인(bound) 식별자이다.
변수의 타입은 생략해도 무방하며, OCaml의 타입 시스템이 타입을 추론해준다.
타 언어와 달리 변수 선언과 초기화를 따로 하는 것이 불가능하며, 변수는 선언과 동시에 값에 bound 되어야 한다.
기본적으로 모든 변수는 값의 변경이 불가능하다. 이 때 같은 이름의 변수를 여러 번 선언하는 경우 가장 최근에 선언한 변수에만 접근 가능하며, 이를 variable shadowing이라 한다.
let x = 1 in (* x는 1이며, 변경 불가능 *)
let x = x + x in (* 새로운 x 가 이전 x + x에 묶임 *)
x (* 이전의 x는 새로운 x에 의해 가려짐(shadowing) *)
1) Global Definitions
-
let [variable] = [expression]의 형태 -
globally하게 정의되었기 때문에, 어디서든 사용 가능
2) Local Definitions
-
`let [variable] = [expression] in [expression] 의 형태
-
in은 변수의scope를 정해준다. -
아래의 예시에서
1 + 2 + 3이 계산된 이후 sum에bound된다.global definition과 다르게 sum은
in다음의 expression에서 밖에 사용될 수 없다.
✔ Wildcard
OCaml 에서 Wildcard _는 패턴 매칭이나 함수 정의, expression 의 실행 등 다양한 용도로 사용된다. anything 이라는 의미를 가지고 있어, 어떤 값이든 가질 수 있다는 뜻을 가진다.
OCaml에서는 사용하지 않는 값을 변수에 바인딩 하는 것을 금지한다.
즉, 단순히 expression을 실행하려면 wildcard를 사용하는 것이 좋다.
- expression 실행
- 패턴 매칭
match expression with
| pattern1 -> ~~~
| _ -> ~~~ (* pattern1에 해당되지 않는 모든 값에 대응함 *)
💡 Sequencing
Sequencing은 연속적인 unit expression의 계산을 수행하는 것을 말한다.
-
;로 연결된 expression을 순차적으로 실행 -
마지막 expression을 제외한 모든 expression의 계산 결과는
unit이어야 한다. -
begin-end expression을 사용하여 명시적으로 표기해주는 것이 일반적이다.
(* Semicolon-only *)
Format.printf "10\n";
Format.printf "20\n";
Format.printf "30\n"
(* begin-end *)
begin
Format.printf "10\n";
Format.printf "20\n";
Format.printf "30\n"
end
(* let-in *)
let _ = Format.printf "10\n" in
let _ = Format.printf "20\n" in
Format.printf "30\n"
💡 Function
OCaml에서 함수는 first-class object 취급을 받는 first-class function이다.
즉, OCaml에서 함수를 다른 함수에 대한 인자로 전달하고, 다른 함수의 값으로 반환하고,
변수에 할당하는 것이 가능하다. (함수 자체가 expression 이자 값임)
-
fun키워드를 통해 함수를 정의할 수 있다. -
let definition또는let-in definition을 활용하여 이름 있는 함수 정의가 가능하다.
(* 기본형 *)
fun [param_list] -> [expression]
fun x -> x + 1 (* 익명 함수 정의 *)
let f = fun x y -> x + y (* 익명 함수를 변수 f에 바인딩 *)
let sum x y = x + y (* 이름 있는 함수 정의 *)
let sum x y = x + y in
Format.printf "Result : %d\n" (sum 3 7)
-
함수의 타입은
arrow로 표기 :type -> type -
여러 인자를 받는 경우
curried form으로 표기한다.
currying : 여러 인자를 받는 함수를 단일 인자를 받는 함수의 나열로 표현
let add x = x + 1 (* add : int -> int *)
let sum x y = x + y (* sum : int -> int -> int *)
-
함수 인자를
tuple로 받도록 정의할 수도 있다. -
tuple의 타입은*를 사용하여 표기한다.
let a = 3, 4 (* p : int * int *)
let b = (3, 'c', "hello") (* b : int * char * string *)
let sum (x, y) = x + y in
Format.printf "Result : %d\n" (sum(1, 3))
- 함수가 자기 자신을 호출하기 위해서는(재귀)
rec키워드와 함께named function으로 정의해야 한다.
let rec factorial = function
| 0 -> 1
| n -> n * factorial (n - 1) (* rec 키워드를 통해 자기 자신 호출 가능 *)
💡 조건문
OCaml에서의 조건문은 if-then-else expression을 통해 작성된다.
-
if [expression1] then [expression2] else [expression3] -
expression1은 반드시bool타입이어야 한다. -
true이면expression2,false이면expression3이다. -
expression2와expression3의 타입은 동일해야 한다.
let rec factorial n =
if n = 0 then 1
else n * factorial (n - 1)
Leave a comment