オプションの引数は、消去することができませんか?
-
13-09-2019 - |
質問
私は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モジュールでます:
# 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;;
所属していません StackOverflow