13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Scalaにおけるカリー化と型推論

Last updated at Posted at 2016-05-28

Scalaにおいて型推論を利用する際にカリー化が利用されることを知ったので、まとめておきます。

型推論について

型推論とは静的型付け言語における言語機能であり、明示的に型を記述しなくてもコンパイラが自動的に型を決定してくれる機能です。

val x = 100  // 型Intを指定しなくても、代入される値からコンパイラが変数xの型を自動で決定する

動的型付けとの違いに関しては、動的型付けと型推論の違いに書いたので参照してみてください。

カリー化について

カリー化 (currying, カリー化された=curried) とは、複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること(あるいはその関数のこと)である。
カリー化 - Wikipedia

カリー化とは複数の引数をとる関数があった場合に、その関数を部分的に引数を受け取ることが出来る関数に変換することです。
誤解される表現として部分適用という言葉がありますが、これはカリー化された関数の一部に引数を渡すことで部分的に引数が適用された関数を生成することです。
そのため部分適用を行う前段階がカリー化ということになります。

val add = (a:Int, b: Int) => a+b // カリー化されていない関数

val curriedAdd = (a:Int) => (b:Int) => a+b // カリー化された関数

val addOne = curriedAdd(1) // カリー化された関数に対して部分適用をすることで、新たな関数を生成

println( addOne(2) ) // 3が出力される

カリー化による型推論

下記のようなカリー化されていない関数に対して関数fを無名関数として渡す場合は、引数の型を指定する必要があります。

def dropWhile[A](l: List[A], f: A => Boolean): List[A]

val list: List[Int] = List(1, 2, 3, 4, 5)
val result = dropWhile(list, (x: Int) => x < 4))

もし引数の型を指定せずに実行した場合は、missing parameter typeというエラーが発生します。

val list: List[Int] = List(1,2,3,4,5)
val result = dropWhile(list, x => x < 4))

dropWhileの第1引数listはList[Int]であるので、第2引数xの型がIntであることは明らかです。そのため無名関数fのxの型を示すのは、少し不自然に感じます。
この問題を解決するには、dropWhileが引数を部分的に受け取るようにする(カリー化)ことで、Scalaはxの型を推論できるようになります。

def dropWhile[A](l: List[A])(f: A => Boolean): List[A]  // dropWhileをカリー化する

val list: List[Int] = List(1, 2, 3, 4, 5)
val result = dropWhile(list)(x => x < 4)  // 型推論が可能となり、型の指定が必要なくなる

カリー化されたdropWhileの呼び出しでは、最初にdropWhile(list)が関数fを引数として受け取る関数を返します。この関数は最初に渡された引数listの型List[Int]により、型パラメーターAがIntとして解釈されます。
そのため無名関数fを引数として渡す際にxの型をコンパイラが推論可能となり型を省略して記述することが可能となります。

他の関数型言語について

上記のカリー化と型推論の話はScalaにおける話であり、関数型言語共通の話では無いようです。

Haskell や OCaml といった他の関数型言語では、完全な推論が提供されるため、型アノテーションが必要になるケースはほぼ存在しない。

Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド

参考文献

Scala関数型デザイン&プログラミング ―Scalazコントリビューターによる関数型徹底ガイド
http://book.impress.co.jp/books/1114101091

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?