Scala関数式プログラミング_コリー化Currying
3350 ワード
Scala関数式プログラミング_コリー化Currying
コリー化
コンピュータ科学において、コリー化(英語:Currying)は、複数のパラメータを受け入れる関数を1つの単一パラメータ(最初の関数の最初のパラメータ)を受け入れる関数に変換し、残りのパラメータを受け入れて結果を返す新しい関数を返す技術である.この技術はChristopher Stracheyが論理学者のハスケル・ガリーと命名したが、Moses Schonfinkelとゴトロブ・フレグが発明した.
例を直接見る
簡単な関数のコリー化は、次のようになります.
実行結果は、
この例は、関数fooFを返し、この関数を再び呼び出す(より一般的には、返された関数を4に適用する)例であり、次に、匿名関数を返します.
これにより関数のコリー化も実現し,mulOneAtATimeは高次関数でもある.この関数はscalaで以下のように簡単に書くことができます.
lambda式とあまり差がなく,変数x,yをバインドした.
さらに複雑な例を見ると、例えば、ローカルテキストファイルのすべての行データを取得する機能を設計し、メイン関数機能は主にファイルストリーム読取ファイルのすべての行を作成し、読取中にローカルファイルが存在するか否かを判断し、ファイルストリームを読み取り、閉じるなどの多くの補助操作を行う必要がある.
function_app_main.scala
このscalaスクリプトを実行すると、
C:\WorkSpace6-scala\scala-train\src\com\usoft>scala function_app_main.scala
あなたが望む結果が見えます.主にこの関数を見てみましょう
この関数は
filename:StringはStringタイプのパラメータfilenameを受信する
(isFileReadable:(File)=>Boolean)パラメータがFileタイプで、Booleanタイプの関数を返します.
(closableStream:(Closeable)=>Unit)Closeableタイプのパラメータを受信し、Unitタイプの関数を返します.
これもコリー化関数のチェーン呼び出しです
参照先:http://nerd-is.in/2013-09/scala-learning-higher-order-functions/
http://hongjiang.info/currying-and-builder-pattern/
http://blog.csdn.net/yangguo_2011/article/details/30730185
============================END============================
コリー化
コンピュータ科学において、コリー化(英語:Currying)は、複数のパラメータを受け入れる関数を1つの単一パラメータ(最初の関数の最初のパラメータ)を受け入れる関数に変換し、残りのパラメータを受け入れて結果を返す新しい関数を返す技術である.この技術はChristopher Stracheyが論理学者のハスケル・ガリーと命名したが、Moses Schonfinkelとゴトロブ・フレグが発明した.
例を直接見る
簡単な関数のコリー化は、次のようになります.
def foo(a: Int): (Int)=>Int = {
println("===1===")
def fooF(b: Int): Int = {
println("===3===")
a * a + b * b
}
println("===2===")
fooF
}
println((foo(3))(4))
実行結果は、
E:\test-scala>scala currying.scala
===1===
===2===
===3===
25
この例は、関数fooFを返し、この関数を再び呼び出す(より一般的には、返された関数を4に適用する)例であり、次に、匿名関数を返します.
// (y: Int) => x * y
def mulOneAtATime(x: Int) = (y: Int) => x * y
println(mulOneAtATime(3)(2))
これにより関数のコリー化も実現し,mulOneAtATimeは高次関数でもある.この関数はscalaで以下のように簡単に書くことができます.
def mulOneAtATime2(x: Int)(y: Int) = x * y
println(mulOneAtATime(3)(2))
lambda式とあまり差がなく,変数x,yをバインドした.
さらに複雑な例を見ると、例えば、ローカルテキストファイルのすべての行データを取得する機能を設計し、メイン関数機能は主にファイルストリーム読取ファイルのすべての行を作成し、読取中にローカルファイルが存在するか否かを判断し、ファイルストリームを読み取り、閉じるなどの多くの補助操作を行う必要がある.
function_app_main.scala
import java.io.{BufferedReader, FileReader, Closeable, File}
def getLinesSelf(filename: String): List[String] = {
getLines(filename)(isReadable)(closeStream)
}
def getLines(filename: String)(isFileReadable: (File) => Boolean)(closableStream: (Closeable) => Unit): List[String] = {
val file = new File(filename)
if (isFileReadable(file)) {
val readerStream = new FileReader(file)
val buffer = new BufferedReader(readerStream)
try {
var list: List[String] = List()
var str = ""
var isReadOver = false
while (!isReadOver) {
str = buffer.readLine()
if (str == null) isReadOver = true
else list = str :: list
}
list.reverse
} finally {
closableStream(buffer)
closableStream(readerStream)
}
} else {
List()
}
}
def isReadable(file: File) = {
if (null != file && file.exists() && file.canRead()) true
else false
}
def closeStream(stream: Closeable) {
if (null != stream) {
try {
stream.close
} catch {
case ex: Throwable => println(ex.getMessage)
}
}
}
val fileName = "d:/test.txt"
val list: List[String] = getLinesSelf(fileName)
println(list.size)
list.foreach(item => println(item))
このscalaスクリプトを実行すると、
C:\WorkSpace6-scala\scala-train\src\com\usoft>scala function_app_main.scala
あなたが望む結果が見えます.主にこの関数を見てみましょう
getLines(filename: String)(isFileReadable: (File) => Boolean)(closableStream: (Closeable) => Unit): List[String]
この関数は
filename:StringはStringタイプのパラメータfilenameを受信する
(isFileReadable:(File)=>Boolean)パラメータがFileタイプで、Booleanタイプの関数を返します.
(closableStream:(Closeable)=>Unit)Closeableタイプのパラメータを受信し、Unitタイプの関数を返します.
これもコリー化関数のチェーン呼び出しです
getLines(filename)(isReadable)(closeStream)
参照先:http://nerd-is.in/2013-09/scala-learning-higher-order-functions/
http://hongjiang.info/currying-and-builder-pattern/
http://blog.csdn.net/yangguo_2011/article/details/30730185
============================END============================