Ocaml의 재귀

Trung Bun

저는 Ocaml을 처음 접했고 재귀 함수를 작성하려고합니다.

이 함수는 쌍 목록을 가져 와서 목록 쌍을 반환합니다.

[(1, 4); (2, 3); (5, 9); (6, 10)]) -> ([1; 2; 5; 6], [4; 3; 9; 10])

그러나 컴파일러는 다음과 같이 말합니다. Error: This expression has type 'a list * 'b list but an expression was expected of type 'a list

줄에 (unzip (List.tl m))

누군가이 오류가 발생한 이유를 설명해 주시겠습니까? 그리고 어쨌든 이것을 고칠 수 있습니까? 대단히 감사합니다!

let rec unzip m =
    if List.length m = 0 then
       ([], [])
    else
       ((fst (List.hd m)) :: (unzip (List.tl m)), (snd (List.hd m)) :: (unzip (List.tl m)))
in 
    unzip m;; 
잭슨 이야기

모든 재귀의 경우 출력 유형이 항상 동일하다는 점에 유의해야합니다.

당신의 unzip기능을 보자 .

[(1, 4); (2, 3); (5, 9); (6, 10)]) -> ([1; 2; 5; 6], [4; 3; 9; 10])

간단히 말해,의 반환 유형 unzip은 def a pair (tuple) 이고 각 요소는 목록입니다. 맞습니까?


그럼 당신의 코드를 보자

let rec unzip m =
    if List.length m = 0 then
       ([], [])
    else
       ((fst (List.hd m)) :: (unzip (List.tl m)), (snd (List.hd m)) :: (unzip (List.tl m)))
in 
    unzip m;;

두 개의 지점이 있습니다. 첫 번째 분기가 반환 ([], [])됩니다. 좋아, 반환 유형 측면에서 두 개의 빈 목록이있는 쌍이고 위에서 설명한 반환 유형과 일치하므로 정확합니다.


두 번째 지점

((fst (List.hd m)) :: (unzip (List.tl m)), (snd (List.hd m)) :: (unzip (List.tl m)))

맞습니까?

두 개의 요소가있는 쌍입니다. 문제 없습니다. 첫 번째 요소를 살펴 보겠습니다.

(fst (List.hd m)) :: (unzip (List.tl m))

(fst (List.hd m))의 헤드에 추가하려고합니다 (unzip (List.tl m)).

::그러나을 사용하여 목록에 무언가를 추가 할 수만 있으므로 ocaml (unzip (List.tl m))은 목록이라고 가정합니다 .

그러나 그것은 unzip처음에 분명히 설명한 함수 응용 프로그램이며 unzip목록을 반환하지 않고 쌍 (튜플)을 반환합니다.

그래서 ocaml은 이해하지 못해서 불평합니다.


위의 내용은 유형 문제에 대한 귀하의 질문에 대한 답변입니다. 그러나 코드에는 더 많은 문제가 있습니다.

1. 잘못된 사용 in

함수가 있다고 가정합니다 f1. 직접 사용할 수 있다는 것을 의미하는 어머니 기능으로 이미지화 할 수 있습니다. 또한에서 f1다른 함수 나 변수 (또는 좀 더 공식적으로 바인딩)를 선언 할 수 있습니다. 함수 내에서 바인딩을 선언 할 때만 let...in.... 당신은 단지 어머니 기능이 있으면 사용하지 않는 in때문에 in where?

에는 그 자체이며 최상위 수준에 unzip있는 하나의 함수 또는 바인딩 만 있습니다 unzip. 따라서 in필요하지 않습니다.

2. 재귀의 잘못된 논리

더 많이 읽고 더 많이 연습해야하므로 여기서 재귀에 대해 설명하는 방법을 모르겠습니다.

그러나 아이디어의 올바른 코드는

let rec unzip = function
  | [] -> ([], [])
  | (x,y)::tl -> 
    let l1, l2 = unzip tl in
    x::l1, y::l2

더 나은 또는 꼬리 재귀 버전을 쫓는 경우 다음과 같습니다.

let unzip l = 
  let rec unzip_aux (l1,l2) = function
    | [] -> List.rev l1, List.rev l2
    | (x,y)::tl -> unzip_aux (x::l1, y::l2) tl
  in 
  unzip_aux ([],[]) l

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사