Function bindings
ML 언어에서 함수를 구현할 때 기본적으로 3가지를 확인을 해야 한다.
- Syntax
- Evalutation
- Type-checking
(*기본적인 형태*)
fun x0 (x1 : t1, ... , xn : tn) = e
(*example*)
fun apply_f( f: int * int -> int, x : int, y:int ) =
...
syntax : fun apply_f( f : int * int -> int, x : int, y : int) =
-> Debugging Errors : 의도한 구성이 틀렸거나, 구성을 하지 않았거나
evalutation : apply_f 함수는 매개 변수로 x, y의 값을 받아 온다.
-> Debugging Errors : 디버깅이 되지만 잘못된 결과 값이 나오거나, 예외 발생, 또는 무한 루프
type-checking : x, y는 int 타입이다. apply_f 함수는 x와 y를 매개 변수로 받기 때문에 int * int type에서 반환 값으로 int이기 때문에 int 타입으로 하나의 결과 값을 반환한다.
-> Debugging Errors : type-check을 작성하지 않을 경우
Tuples and Lists
-pairs (2-tuples)
syntax : (e1, e2)
evaluation : e1, e2는 value v1, v2으로 가정한다면 결과 값은 (v1, v2)로 나온다.
type-checking : 만약 e1의 타입이 t이고 e2의 타입이 g이면 결과 값의 타입은 t * g로 반환된다. (새로운 종류의 타입)
fun swap (pr : int*bool) =
(#2 pr, #1 pr)
fun sum_two_pairs (pr1 : int*int, pr2 : int*int) =
(#1 pr1) + (#2 pr1) + (#1 pr2) + (#2 pr2)
fun div_mod (x : int, y : int) =
(x div y, x mod y)
fun sort_pair (pr : int*int) =
if (#1 pr) < (#2 pr)
then pr
else (#2 pr, #1 pr)
* #1 은 pairs에서 e1에 해당한 값이고 #2는 e2에 해당한 값이다.
Tuples
튜플은 pair과 같거나 더 많은 부분을 가졌다.
• (e1, e2,…, en)
• ta * tb * … * tn
• #1 e, #2 e, #3 e, …
Nesting
pairs과 tuple은 원한다면 nested 할 수 있다.
<example>
val x1 = (7,(true,9)) (* int * (bool*int) *)
val x2 = #1 (#2 x1) (* bool *)
val x3 = (#2 x1) (* bool*int *)
val x4 = ( (3,5),((4,8),(0,false)) )(* (int*int)*((int*int)*(int*bool)) *)
Lists
비어있는 리스트(null) : []
기본적인 리스트 : [e1, e2,... , en]
v1의 값을 가진 e1을 [v2,..., vn] 리스트를 가진 e2에 append 시켜주고 싶을 때('cond') : e1 :: e2
type-checking list operation
null : `a list -> bool
hd : `a list -> `a
tl : `a list -> `a list
<example>
fun sum_list (xs : int list) =
if null xs
then 0
else hd(xs) + sum_list(tl(xs))
fun countdown (x : int) =
if x=0
then []
else x :: countdown (x-1)
fun append (xs : int list, ys : int list) =
if null xs
then ys
else hd (xs) :: append (tl(xs), ys)
<lists of pairs example>
fun sum_pair_list (xs : (int*int) list) =
if null xs
then 0
else #1(hd xs) + #2(hd xs) + sum_pair_list(tl xs)
fun firsts (xs : (int*int) list) =
if null xs
then []
else #1(hd xs) :: firsts(tl xs)
fun seconds (xs : (int*int) list) =
if null xs
then []
else #2(hd xs) :: seconds(tl xs)
fun sum_pair_list2 (xs : (int*int) list) =
(sum_list (firsts xs)) + (sum_list (seconds xs))
Let-expressions
(*기본적인 형태*)
let b1,b2, ... bn in e end
fun countup_from1_better (x : int) =
let fun count (from : int) =
if from = x
then x :: []
else from :: count(from+1)
in
count 1
end
countup_from 1_better 함수는 매개변수 int 타입을 가진 x를 받았다. 해당 함수는 let expression을 사용하였고
let에는 새로운 함수 count 함수가 binding 되어 있으며, count 함수는 매개 변수 int 타입의 from을 받는데 해당 from 변수는 in에서 count 1로 binding 되어 있다. 즉 from은 1의 값을 가졌다.
let에는 함수뿐만 아니라 local 변수를 지정할 수 있다.
Options
syntax : t option
t 변수는 list 타입으로 많이 사용하지만 리스트가 아닌 다른 어떠한 타입이 올 수 있다.
'Computer Science > Programming Language' 카테고리의 다른 글
[프로그래밍 언어론/ ML] Nested Patterns Exceptions tail Recursion -컴도리돌이 (0) | 2020.06.15 |
---|---|
[프로그래밍 언어/ ML] Records, Datatypes, Case Expressions and more - 컴도리돌이 (0) | 2020.06.15 |
[프로그래밍 언어/Racket] Datatype-Style Programming with Lists or Structs and more - 컴도리돌이 (0) | 2020.06.11 |
[프로그래밍언어/Racket] Macros - 컴도리돌이 (0) | 2020.06.04 |
[프로그래밍 언어/Racket] Thunks, Laziness, Streams, Memoization -컴도리돌이 (0) | 2020.05.28 |