2016-10-14 3 views
0

최근에 ocaml에서 코딩을 시작했으며이 프로그래밍 언어는 반환 할 함수를 정의 할 때 유용합니다. 2 개의리스트를 매개 변수로 사용하는 함수 (오름차순 및 int 유형의 요소)를 작성하고 처음 두리스트의 모든 요소를 ​​포함하는리스트를 오름차순으로 리턴하는 함수를 작성하려고합니다.ocaml 함수가 '목록 대신 unit을 반환하도록 요청했습니다.

let inter l1 l2 = 
let rec aux l1 l2 l3= 
if List.hd l1<List.hd l2 then aux (List.tl l1) l2 (List.hd l1 :: l3) 
else (if List.hd l1>List.hd l2 then aux l1 (List.tl l2) (List.hd l2::l3) 
     else (if l1 = [] then List.fold_left (fun x y -> y::x) l3 l2 
      else if l2=[] then List.fold_left (fun x y -> y::x) l3 l1 
    )) 
    in List.rev (aux l1 l2 []);; 

을하지만 그것을 컴파일 할 때, 그것은 나에게이 오류 메시지가 반환 : 나는 함수를 호출 할 때

Error: This expression has type 'a list 
     but an expression was expected of type unit 

이, 그냥 작동을 여기

은 지금까지 그럭저럭 무엇인가 좋아,하지만 그것은 예상대로 작동하지만, 나를 귀찮게하는 것은 오류 메시지이다. 왜 그런지 알 겠어?

추신 : 저는 Emacs - Tuareg Mode를 텍스트 편집기와 컴파일러로 사용합니다.

답변

0

th구문 구조는 표현식입니다. 전체 표현식의 유형은 분기가 리턴하는 표현식의 유형으로 정의됩니다. 분명히, 그들은 같은 유형이어야합니다. else 분기를 지정하지 않은 경우, 생략 된 else 분기가 유형 단위의 표현이라고 가정합니다. if c then eif c then e else()의 줄임말입니다.

표현 :

if l2=[] then List.fold_left (fun x y -> y::x) l3 l1 else() 

그래서 OCaml의이 ()List.fold_left (fun x y -> y::x) l3 l1를 통합하려고 :

if l2=[] then List.fold_left (fun x y -> y::x) l3 l1 

사실에 대한 속기입니다. 그것들은 확실히 다른 유형을 가지고 있습니다. 당신이 명시 적 else 지점을 추가 할 경우, 모든 (정확성에 대해 확실하지)의 유형 체킹이됩니다

let inter l1 l2 = 
let rec aux l1 l2 l3= 
if List.hd l1<List.hd l2 then aux (List.tl l1) l2 (List.hd l1 :: l3) 
else (if List.hd l1>List.hd l2 then aux l1 (List.tl l2) (List.hd l2::l3) 
     else (if l1 = [] then List.fold_left (fun x y -> y::x) l3 l2 
      else if l2=[] then List.fold_left (fun x y -> y::x) l3 l1 else [] 
    )) 
    in List.rev (aux l1 l2 []);; 

귀하의 좌절이있을 수 있습니다 때문에 C와 같은 프로그래밍 언어에 익숙해있는에. OCaml은 C 프로그래밍 스타일을 강요하려고 할 때 좌절 할 수 있습니다. 패턴 매칭은 OCaml의 매우 강력한 기능과 솔루션 간단합니다 :

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

첫 번째 패턴은 "(L1)는 널리스트 인 경우, L2를 돌려"라고합니다. 두 번째 패턴은 "l2가 빈 목록이면 l1을 반환합니다"라고 말합니다. 패턴 3이 테스트 될 때, 우리는 두리스트가 모두 비어 있지 않다는 것을 알기 때문에 그 내용에 패턴 매치를 할 수 있으므로 list.hd 등을 사용할 필요가 없습니다. 우리는 if 문을 사용하여 어떤 머리가 새로운 머리가되는지 결정하고 재귀 할 때 사용할 꼬리를 결정합니다.

OCaml 관용구에 익숙해지면 이러한 솔루션이 자연스럽게 나옵니다.

+1

스타일 문제에 동의 해주세요. 초보자에게 List.hd를 사용하지 말 것을 권장합니다. 일단 패턴 사용에 익숙해지면,이 규칙을 재검토하고 실제로는 더 나은 선택 일 때'List.hd'를 사용하는 것이 좋습니다. – Stefan

+0

설명해 주셔서 감사합니다. 패턴 매칭에 대해서는 알고 있지만 C 스타일 프로그래밍에서 코드를 논리적으로 작성하는 것이 더 쉽다는 것을 알았습니다. 현재 프로그래밍 스타일보다 작성하는 코드가 적기 때문에 익숙해 지려고 노력할 것입니다. – Stevie

관련 문제