LoginSignup
11
10

More than 5 years have passed since last update.

【解答例】Scala ラムダ 超入門

Last updated at Posted at 2015-03-20

Scala ラムダ 超入門の解答例です。

階乗

【問1】次に示す関数factをラムダ式で書き換えてください。

factorial_lambda.scala
val fact : Int => Int = n => {
  n match {
    case 0 => 1
    case n if n > 0 => n * fact(n - 1)
  }
}

println(fact(5))
println(fact(0))
実行結果
120
1

複数の引数

【問2】次に示す関数addをラムダ式で書き換えてください。

add_lambda.scala
val add : (Int, Int) => Int = (x, y) => x + y

println(add(2, 3))
println(add(9, 3))
実行結果
5
12

無名関数

【問3】次に示す関数addを定義せずに、呼び出し側で無名関数にインライン展開してください。

lambda_function_add_inline.scala
println(((x: Int, y: Int) => x + y)(2, 3))
実行結果
5

高階関数

引数

【問4】次に示す関数faddを定義せずに、呼び出し側で無名関数にインライン展開してください。

higher_order_parameter_without_function.scala
println(((g: (Int, Int) => Int) => g(1, 2))((x: Int, y:Int) => x + y))
実行結果
3

戻り値

【問5】次に示す関数addを定義せずに、呼び出し側で無名関数にインライン展開してください。

add_return_value_lambda.scala
println(((x: Int) => (y: Int) => x + y)(1)(2))
実行結果
3

カリー化

【問6】次に示す関数combineを、引数1つずつに分割してネストさせたラムダ式で書き換えてください。

combine_lambda.scala
val combine = (a: Any) => (b: Any) => (c: Any) => a +: b +: List(c)

val a = combine(1)
val b = a(2)
val c = b(3)
println(c)
println(combine('a')('b')('c'))
実行結果
List(1, 2, 3)
List(a, b, c)

部分適用

【問7】次のコードから関数doubleを除去してください。ラムダ式は使わないでください。

double_partial_application.scala
def f(xs: List[Int], g: (Int) => Int) = for (x <- xs) yield g(x)

println(f(List(1,2,3,4,5), (2.*)))
実行結果
List(2, 4, 6, 8, 10)

演算子

【問8】次のコードからラムダ式を排除してください。新しい関数を定義してはいけません。

operator_without_lambda.scala
def f1(g: (Int) => Int) = g(1)
def f2(g: (Int, Int) => Int) = g(2, 3)

// 新しい関数を定義してはいけない
// def sub1(x:Int) = x - 3
// def sub2(x:Int) = 3 - x
// def add(x:Int, y: Int) = x + y

println(f1(3-_))
println(f1(_-(3)))
println(f2(_+_))
実行結果
2
-2
5

再実装

再帰

【問9】map, filter, flip, foldl, foldrを再帰で再実装してください。関数名にはmを付けてください。

recursion.scala
def mmap(g: Int => Int, xs: Seq[Int]): Seq[Int] = {
  xs match {
    case m if m.isEmpty => Seq()
    case xs: Seq[Int] => g(xs.head) +: mmap(g, xs.tail)
  }
}

def mfilter(g: Int => Boolean, xs: Seq[Int]): Seq[Int] = {
  xs match {
    case xs if xs.isEmpty => Seq()
    case xs if g(xs.head) == true  => xs.head +: mfilter(g, xs.tail)
    case xs if g(xs.head) == false => mfilter(g, xs.tail)
  }
}

def mflip[A, B, C](f: (A, B) => C)(x: B)(y: A) = f(y, x)

def mfoldLeft(g: (Int, Int) => Int, z: Int, xs: Seq[Int]): Int = {
  (g, z, xs) match {
    case (g, z, xs) if xs.isEmpty => z
    case (g, z, xs) => mfoldLeft(g, g(z, xs.head), xs.tail)
  }
}

def mfoldRight(g: (Int, Int) => Int, z: Int, xs: Seq[Int]): Int = {
  (g, z, xs) match {
    case (g, z, xs) if xs.isEmpty => z
    case (g, z, xs) => g(xs.head, mfoldRight(g, z, xs.tail))
  }
}

println(mmap((_*2), (1 to 5)))
println(mfilter((x => x < 5), (1 to 9)))
println(mflip(mmap)(1 to 5)(_*2))
println(mfoldLeft((_+_), 0, (1 to 100)))
println(mfoldLeft((_-_), 0, (1 to 5)))
println(mfoldRight((_-_), 0, (1 to 5)))
実行結果
List(2, 4, 6, 8, 10)
List(1, 2, 3, 4)
List(2, 4, 6, 8, 10)
5050
-15
3

foldLeft

【問10】foldLeftreversemaximumminimumを再実装してください。関数名にはmを付けてください。

foldleft_reverse_max_min.scala
def mreverse(xs: Seq[Int]): Seq[Int] = {
  xs.foldLeft(Seq[Int]())((z, n) => n +: z)
}

def maximum(xs: Seq[Int]): Int = {
  xs.foldLeft(xs.head)((z, n) => if (z < n) n else z)
}

def minimum(xs: Seq[Int]): Int = {
  xs.foldLeft(xs.head)((z, n) => if (z > n) n else z)
}

println(mreverse((-5 to 5)))
println(maximum((-5 to 5)))
println(minimum((-5 to 5)))
実行結果
List(5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5)
5
-5

クイックソート

【問11】次に示す関数qsortfilterで書き替えてください。引数にはList型のリストを使用してください。

qsort_filter.scala
def qsort(xs: List[Int]): List[Int] = {
  if (xs.length <= 1) xs
  else {
    val pivot = xs(xs.length / 2)
    qsort(xs.filter(pivot >)) ++
    xs.filter(pivot ==) ++
    qsort(xs.filter(pivot <))
  }
}

println(qsort(List(4, 6, 9, 8, 3, 5, 1, 7, 2)))
実行結果
List(1, 2, 3, 4, 5, 6, 7, 8, 9)

バブル

【問12】次に示すバブルソートの関数bswapfoldRightで書き替えてください。

bsort_foldright.scala
def bsort(list: List[Int]): List[Int] = {
  def bswap(xs: List[Int]): List[Int] = {
    xs.foldRight(List[Int]())((z, n) => {
      n match {
        case n if n.isEmpty => List(z)
        case n => {
          if (z > n.head) n.head :: z :: n.tail
          else z :: n.head :: n.tail
        }
      }
    })
  }
  val ys = bswap(list)
  ys match {
    case list if ys.isEmpty => List()
    case list => ys.head :: bsort(ys.tail)
  }
}

println(bsort(List(4,3,1,5,2)))
println(bsort(List(4,6,9,8,3,5,1,7,2)))
実行結果
List(1, 2, 3, 4, 5)
List(1, 2, 3, 4, 5, 6, 7, 8, 9)

sum

【問13】Yコンビネータを使って関数sumを再実装してください。

sum_y.scala
def Y[A,B]( f:((A => B), A ) => B, x:A ):B = f( ( y:A ) => Y( f,y ),x )

val y = Y( (f:Seq[Int] => Int , n:Seq[Int]) => n match {
  case n if n.isEmpty => 0
  case _ => n.head + f(n.tail)
}, (1 to 100))

println(y)
実行結果
5050
11
10
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
11
10