プログラミングの基礎 > 第4章 関数の定義

4.3 関数の型

OCamlは強く型付けされたプログラミング言語であり、プログラム中に現れるすべてのデータに型が付いています。
この性質は関数についても成り立っており、OCamlに出てくる関数にはすべて型が付いています。

引数と返り値の型

# let f x = 3 * x ;;
val f : int -> int = <fun>

「val f : int -> int = <fun>」というOCamlインタープリターの返答に注目します。
関数fは「int -> int」という型を持っています。

  • 1つ目のint=引数の型
  • 2つめのint=返り値の型

関数fは、整数型の引数を1個受け取り、整数型の返り値を1個返す、という形になっているので、関数fの型は「int -> int」となっているのですね。

関数の型の表記には、「->」という矢印記号が含まれていることが特徴です。

返り値の型

# f 4 ;;
- : int = 12

関数fの返り値は整数型になっています。
整数4を3倍した答は、整数12です。
「 - : int = 12」は、12が整数型であることを示しています。

ここで注意したいのは、

  • 関数の型
  • 関数の返り値の型
    は別物であり、混同しないようにするということです。

<fun>

「<fun>」という記号、表記は、定義されたfが関数であることを示しています。
fun=function(関数)の省略ですね。

引数が複数ある場合

# let g x y = x * x + y * y - 4 ;;
val g : int -> int -> int = <fun>
# g 3 2 ;;
- : int = 9

引数が「x」と「y」の2個ある関数gを定義してみました。
関数gの型は「int -> int -> int」となっています。
intが3つになってますね。

これは、

  • 1つめのint=引数xの型
  • 2つめのint=引数yの型
  • 3つめのint=返り値の型
    を表しています。

一般的に関数の型で、

A -> B -> C

となっていた場合、矢印記号は「右結合」になっています。
つまり、

(A -> B) -> C

ではなく、

A -> (B -> C)

という意味です。

これで、
1つ目の引数としてA型の値を受け取り、
2つ目の引数としてB型の値を受け取ったら、
結果としてC型の当たりを返す
という関数の型を表します。

カリー化

複数の引数を受け取る関数は、1個の引数を受け取る関数の組合せに分解できます。
関数型プログラミングの用語で、関数を分解することを「カリー化」と言います。

  • カリー化 - Wikipedia

    カリー化 (currying, カリー化された=curried) とは、複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること(あるいはその関数のこと)である。
    クリストファー・ストレイチーにより論理学者ハスケル・カリーにちなんで名付けられたが、実際に考案したのはMoses Schönfinkelとゴットロープ・フレーゲである。
    ごく簡単な例として、f(a, b) = c という関数 f があるときに、F(a) = g(ここで、g は g(b) = c となる関数である)という関数 F が、f のカリー化である。
    カリー化とは直感的には、「関数の複数引数を、1引数ずつ順に、バラバラにする」ということである。

A -> (B -> C)

は、「関数がカリー化できる(分解できる)」という意味も含まれている、と考えれば分かりやすいでしょうか?


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-08-07 (水) 08:31:25 (1714d)