무냐의 개발일지
[OSSU] <Programming Language, Part A> / Week3 본문
순서는 상관없다. 어차피 매칭된 key의 값들이 있는거니까
값이 많아질수록 tuples(position으로 접근)보다는 records(name으로 접근) 형식으로 쓰는게 당연히 기억하지 않아도 되고 편하겠지
mytype은 이 타입들 중 하나이다
| Pattern Matching
datatype mytype = TwoInts of int * int
| Str of string
| Pizza
fun f x =
case x of
Pizza => 3
| Str s => 8
| TwoInts(i1,i2) => i1 + i2
(* | Pizza => 4; (* redundant case: error *) *)
(*fun g x = case x of Pizza => 3 (* missing cases: warning *) *)
f Pizza;
f (Str "hi");
f (Str "whatup");
f (TwoInts(3,4));
f (TwoInts(50,5));
#결과
-
val it = 3 : int
val it = 8 : int
val it = 8 : int
val it = 7 : int
val it = 55 : int
-
| 중복 불가
option으로 들어간다?? 이름은 일단 무조건 있어야하고, ID랑 미들네임은 있어도 없어도 되는거니까 option으로 넣는다
| Type Synonyms
| Lists and Options are Datatypes
sum_list xs : xs 리스트 안에 있는 모든 숫자를 합치겠다
append(xs, ys) : xs를 ys리스트에 붙이겠다
| Pattern Matching
ML에서 함수는 실제로 오직 1개만의 변수를 갖는다. 그걸 가지고 함수 본문이 pattern matching을 통해, 튜플의 1번째, 2번째... n번째에 대해 어떤 작업을 할지 작동하는 것임!!
| Type Inference
주어진 변수 내에서 몇 개만 사용한다고 했을 때, 함수 본문에 사용되지 않는 변수는 int 같은 타입이 아니라, 좀 더 general한 타입인 'a 이런 식으로 표현이 된다. 괜찮다.
| 그렇다면 뭐가 더 General 한 타입이지??
polymorphic type is more general
| Nested Patterns
ZIP
(* do this *)
fun zip3 list_triple =
case list_triple of
([],[],[]) => []
| (hd1::tl1,hd2::tl2,hd3::tl3) => (hd1,hd2,hd3)::zip3(tl1,tl2,tl3)
| _ => raise ListLengthMismatch
(* _ means else. if not matches none of above cases, then _ *)
UNZIP
(* and the inverse *)
fun unzip3 lst =
case lst of
[] => ([],[],[])
| (a,b,c)::tl => let val (l1,l2,l3) = unzip3 tl
in
(a::l1,b::l2,c::l3)
end
More of Nested Patterns
(* another elegant use of "deep" patterns *)
fun nondecreasing xs =
case xs of
[] => true
| x::[] => true
| head::(neck::rest) => (head <= neck andalso nondecreasing (neck::rest))
x 대신 _ 를 쓰는게 더 세련됐다. 특정 변수가 아니라, 그냥 '뭐라도 있으면' 이라는 뜻임!
datatype sgn = P | N | Z
fun multsign (x1,x2) =
let fun sign x = if x=0 then Z else if x>0 then P else N
in
case (sign x1,sign x2) of
(Z,_) => Z
| (_,Z) => Z
| (P,P) => P
| (N,N) => P
| _ => N (* many say bad style; I am okay with it --> (N,P), (P,N) => N *)
end
(* simpler use of wildcard pattern for when you do not need the data *)
요런식으로 안에 nested 형태로 쓰면 훨씬 간결하고 깔끔해진다
fun len xs =
case xs of
[] => 0
| _::xs' => 1 + len xs'
| Pattern Matching
| Exceptions
raise : 예외를 발생시킨다. 값을 데려오지 않는다 .
| Tail Recursion
이거는 fact를 부를때마다 앞에 n을 곱해주는 추가작업을 해주지만
이거는 그냥 aux(n-1, acc*n) 자체를 부르고 다른 추가작업은 안해준다. 이게 더 효율적이라고 한다.
스택을 따로 만드는게 아니라, fact 프레임을 aux 프레임으로 바꾸고, 이대로 쭉 가서 끝나는거다. aux(0,6)을 반환하면 즉시 답을 얻는다.
'OSSU_CS coursework' 카테고리의 다른 글
[OSSU] <Programming Language, Part A> / Week5 (0) | 2024.05.30 |
---|---|
[OSSU] <Programming Language, Part A> / Week4 (0) | 2024.05.28 |
[OSSU] <Programming Language, Part A> / Week2 (0) | 2024.05.19 |
[OSSU] <Programming Language, Part A> / Week1 _SML/NJ 설치 방법 (오류 수정) (0) | 2024.05.18 |
[OSSU] <UBCx HtC1x_How to Code> / 10_Accumulator (0) | 2024.05.11 |