質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

OCaml

OCaml(オーキャムル)は、フランスのINRIAが開発した関数型言語MLの一種で、 最新の言語理論の成果が取り入れられているプログラミング言語です。

Q&A

解決済

1回答

1573閲覧

ocamlによる内積

grape_ll

総合スコア83

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

OCaml

OCaml(オーキャムル)は、フランスのINRIAが開発した関数型言語MLの一種で、 最新の言語理論の成果が取り入れられているプログラミング言語です。

0グッド

0クリップ

投稿2021/05/15 07:04

[[1;4];[2;5];[3;6]] (これをlistと名付けます)
これを
map関数によって各要素の積を取って,それをList.fold_rightによって総和を取るということをしたいです.

詰まっているのは,map関数を使い方で,上記のように使うために

map (fun x y -> x*y) list

としたのですが,うまく動いてくれません.記述の仕方が間違っているようなのですが,これはどのように書けば正しく動作しますでしょうか.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

List.map関数に渡している匿名関数fun x y -> x * yですが、引数を2つ取っています。しかしmaplistの要素を1つずつ取り出して匿名関数に渡しますので、匿名関数は引数を1つだけ取るように定義されていないといけません。

たとえばlist[[1; 4]; [2; 5]; [3; 6]]なら、匿名関数には最初に[1; 4]という値が1つだけ渡されます。(14の2つの値ではありません)

つまり匿名関数は引数として[1; 4]をとり、その引数をmatchによるパターンマッチングでxyに分解しないといけません。

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/15 15:06

tatsuya6502

総合スコア2035

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

grape_ll

2021/05/16 01:02

丁寧な解説ありがとうございます. warningについての対処も納得いたしました.参考にさせていただきます.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問