Skip to content

Instantly share code, notes, and snippets.

@1206yaya
Created January 21, 2015 10:25
Show Gist options
  • Save 1206yaya/c760a5ee2faf044a9631 to your computer and use it in GitHub Desktop.
Save 1206yaya/c760a5ee2faf044a9631 to your computer and use it in GitHub Desktop.
制御の抽象化 カリー化 _ ローンパターン
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