高階関数
2015年 5月 7日 関数型プログラミング Kotlin Swift Ruby
Scala関数型デザイン&プログラミングで学んでいる関数型プログラミングですが、今回は高階関数です。
課題2.2 指定された比較関数に従ってArray[A]がソートされているかどうかを調べるisSortedを実装せよ。
Scalaでの回答
scala
def isSorted[A](as: Array[A], gt: (A,A) => Boolean): Boolean = {
@annotation.tailrec
def go(n: Int): Boolean =
if (n >= as.length-1) true
else if (gt(as(n), as(n+1))) false
else go(n+1)
go(0)
}
Kotlin
KotlinはScalaと同じく総称関数(Generic Function)を使用できるのでほぼそのまま。
kotlin
fun isSorted<A>(arr: Array<A>, gt: (A, A) -> Boolean): Boolean {
fun go(n: Int): Boolean {
if (n >= arr.size() - 1) return true
else if (gt(arr[n], arr[n + 1])) return false
else return go(n + 1)
}
return go(0)
}
使い方はこんなかんじです。
kotlin
fun main(string: Array<String>) {
val arr = array(1, 2, 3, 4)
val result = isSorted<Int>(arr, {a, b -> a > b})
println(result)
}
Swift
Swiftも総称関数が使えるようです。
ローカル関数で再帰ができないので、nの初期値を与えて使います。
kotlin
func isSorted<A>(n: Int, arr: Array<A>, gt: (A, A) -> Bool) -> Bool {
if (n >= arr.count - 1) {
return true
} else if (gt(arr[n], arr[n + 1])) {
return false
} else {
return isSorted(n + 1, arr, gt)
}
}
let arr = [1, 2, 3, 4]
let result = isSorted(0, arr, {(a, b) in a > b})
println(result)
Ruby
Rubyはネストしたメソッドで外側の変数を参照できないので、(Ruby のネストしたメソッドと、変数のスコープ)
配列とProcをネストしたメソッドに渡しています。
ruby
def is_sorted(as, gt)
def go(n, as, gt)
if n >= as.length - 1
true
elsif gt.call(as[n], as[n + 1])
false
else
go(n + 1, as, gt)
end
end
go(0, as, gt)
end
as = [1, 2, 3, 4]
result = is_sorted(as, lambda {|a, b| a > b})
p result