以前のソリューションはコンパイルされますが、期待される結果は得られません。関数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.]