List.map
関数に渡している匿名関数fun x y -> x * y
ですが、引数を2つ取っています。しかしmap
はlist
の要素を1つずつ取り出して匿名関数に渡しますので、匿名関数は引数を1つだけ取るように定義されていないといけません。
たとえばlist
が[[1; 4]; [2; 5]; [3; 6]]
なら、匿名関数には最初に[1; 4]
という値が1つだけ渡されます。(1
と4
の2つの値ではありません)
つまり匿名関数は引数として[1; 4]
をとり、その引数をmatch
によるパターンマッチングでx
とy
に分解しないといけません。
ocaml
1fun elem -> match elem with
2 | [x; y] -> x * y
3
4(* 上の関数はfunctionを使うと簡潔に書ける *)
5
6function [x; y] -> x * y
これで実行できるようになり、期待どおりの値[4; 10; 18]
が得られます。
ocaml
1# let list = [[1; 4]; [2; 5]; [3; 6]];;
2val list : int list list = [[1; 4]; [2; 5]; [3; 6]]
3
4# List.map (function [x; y] -> x * y) list;;
5Warning 8 [partial-match]: this pattern-matching is not exhaustive.
6Here is an example of a case that is not matched:
7_::_::_::_
8- : int list = [4; 10; 18]
なお、上の例では匿名関数の定義時にpartial-match
という警告がでていますが、これは[x; y]
というパターンが、長さ2のリストにしかマッチしないからです。この定義では、空のリスト[]
や、長さが1や3のリストが来たときに、それに一致するパターンがないため実行時例外が発生します。
ocaml
1# let list = [[]; [1]; [2; 3]];;
2val list : int list list = [[]; [1]; [2; 3]]
3
4# List.map (function [x; y] -> x * y) list;;
5Warning 8 [partial-match]: this pattern-matching is not exhaustive.
6Here is an example of a case that is not matched:
7_::_::_::_
8Exception: Match_failure ("//toplevel//", 1, 9).
これを回避するには[1; 4]
のようなリスト(int list
型)ではなく、(1, 4)
のような組((int * int)
型)を使うのがいいでしょう。組なら長さが2と決まっていますので、実行時例外が発生する心配がありません。
ocaml
1# let list = [(1, 4); (2, 5); (3, 6)];;
2val list : (int * int) list = [(1, 4); (2, 5); (3, 6)]
3
4# List.map (function (x, y) -> x * y) list;;
5- : int list = [4; 10; 18]
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/16 01:02