문제

나는 꼬리 재귀 버전을 갖고 싶었습니다. List.map, 그래서 제가 직접 썼습니다.여기있어:

let rec list_map f l ?(accum=[])=
  match l with
      head :: tail -> list_map f tail ~accum:(head :: accum)
    | [] -> accum;;

이 함수를 컴파일할 때마다 다음과 같은 결과를 얻습니다.

File "main.ml", line 69, characters 29-31:
Warning X: this optional argument cannot be erased.

그만큼 지도 시간 이는 선택적 인수가 아닌 함수를 만들려고 한다는 의미입니다.그러나 위의 함수는 분명히 선택적이지 않은 인수를 취합니다.

아마 내가 정말 멍청한 짓을 하고 있는 것 같은데, 뭐?

도움이 되었습니까?

해결책

이전 솔루션은 컴파일하지만 예상 결과는 제공하지 않습니다. 함수 f 논증에 적용되지 않습니다. 올바른 코드는 다음과 같습니다.

let rec list_map f ?(accum = []) l = match l with
    | head :: tail -> list_map f ~accum:(f head :: accum) tail
    | [] -> accum;;

추론 된 유형은 다음과 같습니다.

val list_map : ('a -> 'b) -> ?accum:'b list -> 'a list -> 'b list = <fun>

... 잘못된 것과는 달리 :

val list_map : 'a -> ?accum:'b list -> 'b list -> 'b list = <fun>

결과 목록이 반대로됩니다.

# list_map ( ( ** ) 2.) [1.;2.;3.;4.];;
- : float list = [16.; 8.; 4.; 2.]

... 그리고 함수와 같습니다 목록 모듈에서 rev_list:

# List.rev_map ( ( ** ) 2.) [1.;2.;3.;4.];;
- : float list = [16.; 8.; 4.; 2.]

따라서 기능을 다음과 같이 변경할 수 있습니다.

let rec list_map f ?(accum = []) l = match l with
    | head :: tail -> list_map f ~accum:(f head :: accum) tail
    | [] -> List.rev accum;;

... 이는 (매뉴얼에 따라) 꼬리 수익성이어야하고 원래 순서로 목록을 반환해야합니다.

# list_map ( ( ** ) 2.) [1.;2.;3.;4.];;
- : float list = [2.; 4.; 8.; 16.]

다른 팁

예, 비선택적 인수는 마지막일 수 없습니다. 왜냐하면 OCaml은 부분적 적용을 지원하기 때문에 마지막 선택적 인수가 누락된 함수는 여전히 선택적 인수를 찾고 있는 부분적으로 적용된 함수처럼 보일 것이기 때문입니다.선택적 인수를 제공할 의도가 없음을 알 수 있는 유일한 방법은 그 뒤에 인수를 제공했음을 확인하는 것입니다.

마지막으로 가지고 있어야한다면 더미를 넣을 수 있습니다 unit 그 이후의 주장:

let rec list_map f l ?(accum=[]) () =
  match l with
      head :: tail -> list_map f tail ~accum:(head :: accum) ()
    | [] -> accum;;

하지만 이 경우에는 순서를 바꾸는 것이 더 좋습니다.

비 옵션 논쟁이 필요합니다 ~ 후에 선택 사항. 기능의 인수 순서를 변경하십시오.

let rec list_map f ?(accum=[]) l=
  match l with
    head :: tail -> list_map f  ~accum:(head :: accum) tail
  | [] -> accum;;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top