Created
January 21, 2015 10:25
-
-
Save 1206yaya/c760a5ee2faf044a9631 to your computer and use it in GitHub Desktop.
制御の抽象化 カリー化 _ ローンパターン
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package PSSE.code | |
import java.io.PrintWriter | |
object FileMatcher extends App { | |
private def filesHere = (new java.io.File("/tmp/scalaLesson/")).listFiles | |
// def filesEnding(query: String) = | |
// for (file <- filesHere; if file.getName.endsWith(query)) | |
// yield file | |
// 2個の文字列引数(ファイル名と基準の文字列)をとり、Booleanを返す。 | |
def filesMatching(query: String, matcher: (String, String) => Boolean) = { | |
for (file <- filesHere; if matcher(file.getName, query)) | |
yield file | |
} | |
def filesEnding(query: String) = | |
filesMatching(query, _.endsWith(_)) | |
// _.endsWith(_) は (fileName: String, query: String) => fileName.endsWith(query) | |
// (fileName, query) => fileName.endsWith(query) とも書ける | |
// で、パラメータの順序が一緒なので _ というプレースホルダが使える | |
def filesContaining(query: String) = | |
filesMatching(query, _.contains(_)) | |
def filesRegex(query: String) = | |
filesMatching(query, _.matches(_)) | |
println(filesEnding("mo.")) | |
println(filesRegex("mo.")) | |
} | |
// filesEnding, filesContaining, filesRegexから query パラメータを除去 | |
object FileMatcherClosures { | |
private def filesHere = (new java.io.File("/tmp/scalaLesson/")).listFiles | |
private def filesMatching(matcher: String => Boolean) = | |
for (file <- filesHere; if matcher(file.getName)) | |
yield file | |
def filesEnding(query: String) = | |
filesMatching(_.endsWith(query)) | |
def filesContaining(query: String) = | |
filesMatching(_.contains(query)) | |
def filesRegex(query: String) = | |
filesMatching(_.matches(query)) | |
} | |
object ControlAbstraction extends App{ | |
private def filesHere = (new java.io.File("/tmp/scalaLesson/")).listFiles | |
// def containsNeg(nums: List[Int]): Boolean = { | |
// var exists = false | |
// for (num <- nums) | |
// if (num < 0) | |
// exists = true | |
// exists | |
// } | |
// 渡されたListをレシーバーとして高階関数のexistsを呼び出す | |
def containsNeg(nums: List[Int]) = nums.exists(_ < 0) | |
println(containsNeg(List(1, 2, -3, 4))) | |
// リストに奇数が含まれているかどうかをテストする | |
// def containsOdd(nums: List[Int]): Boolean = { | |
// var exists = false | |
// for (num <- nums) | |
// if (num % 2 == 1) | |
// exists = true | |
// exists | |
// } | |
def containsOdd(nums: List[Int]) = nums.exists(_ % 2 == 1) | |
println(containsOdd(List(1, 3))) | |
println("------------------- カリー化 -------------------") | |
// ふつうの関数 | |
def plainOldSum(x: Int, y: Int) = x + y | |
println(plainOldSum(1, 2)) // 3 | |
// カーリー化 | |
def curriedSum(x: Int)(y: Int) = x + y | |
println(curriedSum(1)(2)) // 3 | |
// 二回の手順にわけて | |
def first(x: Int) = (y: Int) => x + y | |
val second = first(1) | |
println(second(2)) // 3 | |
// curriedSumも「第二の関数」に当たる参照を手に入れる | |
val onePlus = curriedSum(1)_ | |
println(onePlus(2)) // 3 | |
println("------------------- 新しい制御構造を作る -------------------") | |
// 同じ操作を2度繰り返して結果値を返す | |
// opの型はDouble=>Doubleであり、これは引数として1個のDoubleをとり、結果値としてDoubleを返す関数を意味する。 | |
def twice(op: Double => Double, x: Double) = op(op(x)) | |
println(twice(_ + 2, 5)) | |
} | |
import java.io._ | |
object WithPrintWriter1 { | |
def withPrintWriter(file: File, op: PrintWriter => Unit) { | |
val writer = new PrintWriter(file) | |
try { | |
op(writer) | |
} finally { | |
writer.close() | |
} | |
} | |
def main(args: Array[String]) { | |
withPrintWriter( | |
new File("/tmp/scalaLesson/date.txt"), | |
writer => writer.println(new java.util.Date) | |
) | |
} | |
} | |
import java.io._ | |
object WithPrintWriter2 { | |
// ローンパターンを使ったファイルへの書き込み | |
def withPrintWriter(file: File)(op: PrintWriter => Unit) { | |
val writer = new PrintWriter(file) | |
try { | |
op(writer) | |
} finally { | |
writer.close() | |
} | |
} | |
def main(args: Array[String]) { | |
val file = new File("/tmp/scalaLesson/date.txt") | |
withPrintWriter(file) { | |
writer => writer.println(new java.util.Date) | |
} | |
} | |
} | |
object Assert{ | |
var assertionsEnabled = true | |
// パラメータとして関数値をとり、外部のフラグを見てアサーションを行うかどうかを決める。 | |
def myAssert(predicate: () => Boolean) = | |
if (assertionsEnabled && !predicate()) | |
throw new AssertionError | |
def byNameAssert(predicate: => Boolean) = | |
if (assertionsEnabled && !predicate) | |
throw new AssertionError | |
def main(args: Array[String]) { | |
try { | |
myAssert(() => 5 > 3) | |
println("5 > 3") | |
myAssert(() => 5 < 3) | |
} catch { | |
case ex: AssertionError => println("ex [" + ex + "]") | |
} | |
try { | |
byNameAssert(5 > 3) | |
println("5 > 3") | |
byNameAssert(5 < 3) | |
} catch { | |
case ex: AssertionError => println("ex [" + ex + "]") | |
} | |
println(byNameAssert(5 > 3)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment