以前的解决方案可以编译,但不会给出预期的结果。该函数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.]
...并等于List 模块中的函数 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.]