게시판 인덱스

 
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 

ocaml 코딩 팁? 자주하는 실수 등등..

 
이 게시판은 잠겼으므로 글을 올리거나, 답변을 하거나 수정을 할 수 없습니다   이 주제는 잠겼으므로 답변을 하거나 수정을 할 수 없습니다     게시판 인덱스 -> 4190.210 Principles of Programming (Fall 2009)
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
윤용호



가입: 2008년 9월 23일
올린 글: 257

올리기올려짐: 2009년10월28일 0:43    주제: ocaml 코딩 팁? 자주하는 실수 등등.. 인용과 함께 답변

1.

martini에 putty로 접속해서 vi로 작업하는 분들이 꽤 있을텐데

인코딩 설정을 제대로 해주지 않으면 한글이 깨져 나오기도 하고

편집 도중에 내려갔다 올라오면 라인이 뒤죽박죽이 되어 보이기도 하고

여러모로 불편합니다.

한글 putty 사용자의 경우 putty를 처음 켜고 나서

왼쪽 트리 메뉴중 창->변환을 선택하시면

"수신한 데이터를 이 문자셋으로 가정"이라는 부분이 있는데

이 부분을 UTF-8로 골라주시면 한글이 깨지지 않습니다.

영문 putty도 대충 비슷한 의미를 갖는 메뉴에 있으니 잘 찾아보세요.


매번 이렇게 설정하기가 귀찮겠죠?

한번 UTF-8로 설정한 이후, 다시 '세션' 메뉴로 돌아가서

호스트이름에 martini.snucse.org를 입력한 후

바로 밑에 "저장된 세션"에다가 martini나 마티니 등 적당한 이름을 입력하고

저장을 누릅니다. 그럼 앞으로는 저장된 세션 리스트에서 martini를 더블클릭하면

자동으로 인코딩 설정이 된 상태로 접속이 가능합니다. (주소 입력하는 수고도 덜어주죠)


2.

ocaml의 "apply"는 항상 왼쪽 우선입니다.

사실 lambda calculus가 왼쪽 우선으로 결합하도록 되어있으니
옳다고 볼수도 있긴 하지만 코딩을 하는 입장에서는
syntax가 불편한 면이 있습니다.

예를 들어, string을 내부에 갖는 이런 예외를 선언했다고 칩시다.
exception Unbound_variable of string

이 error를 raise 할 때는 다음과 같이 괄호로 싸주어야 합니다.
(raise도 일종의 함수라고 하는군요. exn -> 'a)

raise (Unbound_variable id) <- 이것이 맞습니다.

raise Unbound_variable id 와 같이 표현하면
(raise Unbound_variable) id 가 되어서
Unbound_variable이 argument를 필요로 한다는 에러를 내뱉게 됩니다.

raise는 좀 따로 취급해줬으면 좋았을텐데 아쉽다는 생각이 드는군요.


혹은 다음과 같이 match를 한다고 생각해봅시다.
match x with
None -> 0
| Some [] -> 0
| Some h::t -> 0

여기서도 문제가 생깁니다. :: 보다 apply가 우선이기 때문에
매칭할때 (Some h)::t 인것처럼 인식합니다. 당연히 타입에러가 나겠죠.

또 다른 예로 List.map으로 다음과 같은 작업을 하려고 합니다.
List.map (function x->x+1) 1::2::3::[]

원하는 결과는 [2;3;4] 이겠지만 역시 타입 에러가 납니다.

((List.map (function x->x+1)) 1)::2::3::[] 로 인식하기 때문에..

List.map (function x->x+1) (1::2::3::[]) 로 입력해야 올바른 결과를 얻을 수 있습니다. (function apply가 왼쪽 오른쪽 관계 없이 ::보다 우선순위가 높습니다. 이 예는 밑에 다시 나옵니다)


3.

match를 이중으로 써야할 경우가 종종 있습니다.

혹은 match 하던 중에 속에서 try ... with 구문을 사용할 일도 있겠지요.

이때는 안쪽의 match를 괄호로 또 싸주어야 합니다.

예를 들어

type test = Int of int | String of string
exception Error of string

...
match x with
Int i -> try 10/i with Division_by_zero -> 10
| String s -> try int_of_string s with Failure msg -> 0
...

이러면 에러가 나지요. 왜냐면 try ... with 의 Divison_by_zero에 이어서 | String s -> 의 매칭을 시도하는 것으로 인식하기 때문입니다. exception들 매칭하다가 갑자기 String을 매칭하려고 하니 에러가 날수밖에..

저기선 try를 사용했지만
match 안에 match가 또 들어갈 때도 꽤 있는데
이때 일일이 괄호로 싸주어야 합니다.

match x with
Int i -> (try 10/i with Division_by_zero -> 10)
| String s -> (try int_of_string s with Failure msg -> 0)


중첩된 match 구문의 예 :
let rec merge l1 l2 = match l1 with
[] -> l2
| h1::t1 -> (match l2 with
    [] -> l1
    | h2::t2 -> if h1<h2 then h1::merge t1 l2
              else h2::merge l1 t2
      )

보기엔 뭔가 어색하죠? h1::merge t1, l2 ? 하지만 맞는 표현입니다.

# List.map (function x->x) [1;2]::List.map (function x->x+1) [1;2]::[] ;;
- : int list list = [[1; 2]; [2; 3]]

이 결과에서 볼 수 있듯, ::은 항상 function apply보다 우선순위가 낮습니다.


4.
match에서 이름을 붙일 필요 없는 값들은 생략이 가능합니다.
type exp = Int of int | String of string | Float of float | Plus of exp * exp

let is_int e =
match e with
Int _ -> true
| _ -> false

이런식으로도 사용 가능합니다. Int 이기만 하면
내부의 값이 무엇이든 상관 없으므로 _로 무시하겠다고 해줄 수 있습니다.
또 마지막의 _ 역시 "Int가 아닌 모든것" 이라는 의미로 사용 가능합니다.
if .. else if .. else 에서 else와 비슷하다고 생각하셔도 좋습니다.
단, 위의 matching에서 모든 케이스들을 다 다루었을 경우
맨 밑에 _을 붙이면 필요없는 매칭이라며 warning이 뜰 것입니다.

또 다른 match의 강력함은 이름 붙인 값 하나에 대해서만 쓸수 있는게 아니라는 점입니다.

let same_type e1 e2 = match (e1,e2) with
(Int _, Int _) -> true
| (String _, String _) -> true
| (Float _, Float _) -> true
| (Plus _, Plus _) -> true
| _ -> false

이런식으로도 응용이 가능합니다.

이걸 이용하면 위의 merge 예시도 다시 만들 수 있습니다.

let rec merge l1 l2 = match (l1, l2) with
([], _) -> l2
| (_, []) -> l1
| (h1::t1, h2::t2) -> if h1<h2 then h1::merge t1 l2 else h2::merge l1 t2;;

2중으로 match를 쓰는 것 보다 보기 좋은 것 같네요.


////////////////////////////////////////

scheme은 syntax때문에 헷갈일 일은 별로 없었는데(무식한 괄호들 덕에)

ml은 syntax도 고려해서 코딩을 해야하니

무의미한 삽질을 줄여보고자 올려봅니다.

다른 팁들 알고계신 분들도 리플로 공유해보아요.
_________________
TA
위로
사용자 정보 보기 비밀 메시지 보내기
이전 글 표시:   
이 게시판은 잠겼으므로 글을 올리거나, 답변을 하거나 수정을 할 수 없습니다   이 주제는 잠겼으므로 답변을 하거나 수정을 할 수 없습니다     게시판 인덱스 -> 4190.210 Principles of Programming (Fall 2009) 시간대: GMT + 9 시간(한국)
페이지 11

 
건너뛰기:  
새로운 주제를 올릴 수 없습니다
답글을 올릴 수 없습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다


Powered by phpBB 2.0.21-7 (Debian) © 2001, 2005 phpBB Group
Translated by kss & drssay