1. 程式人生 > >《快學Scala》習題詳解 第12章 高階函式

《快學Scala》習題詳解 第12章 高階函式

1 編寫函式values(fun: (Int) => Int, low: Int, high: Int),該函式輸出一個集合,對應給定區間內給定函式的輸入和輸出。比如,values(x => x * x, -5, 5)應該產出一個對偶的集合(-5, 25), (-4, 16), (-3, 9), …, (5, 25)

  var arr = ArrayBuffer[(Int, Int)]()
  def values(fun: (Int) => Int, low: Int, high: Int) {
    for (elem <- low to high)
      arr
+= ((elem, fun(elem))) } values(x => x * x, 5, 10) arr map (println)

2 如何用reduceLeft得到陣列中的最大元素?

  val arr = Array(3, 6, 6, 0, 1)
  def f(a: Int, b: Int): Int = {
    if (a > b) a
    else b
  }
  println(arr.reduceLeft(f))

3 用to和reduceLeft實現階乘函式,不得使用迴圈或遞迴


  def f(n:Int){
    println(1
to n reduceLeft (_ * _)) }

4 前一個實現需要處理一個特殊情況,即n<1的情況。展示如何用foldLeft來避免這個需要。(在scaladoc中查詢foldLeft的說明。它和reduceLeft很像,只不過所有需要結合在一起的這些值的首值在呼叫的時候給出。)

    println((1 to n).foldLeft(1)(_ * _))

5 編寫函式largest(fun: (Int) => Int, inputs: Seq[Int]),輸出在給定輸入序列中給定函式的最大值。舉例來說,largest(x => 10 * x - x * x, 1 to 10)應該返回25。不得使用迴圈或遞迴

  def largest(fun: (Int) => Int, inputs: Seq[Int]) {
    println(inputs.map { fun }.max)
  }
  largest(x => x * x, (1 to 5))

6 修改前一個函式,返回最大的輸出對應的輸入。舉例來說,largestAt(fun: (Int) => Int, inputs: Seq[Int])應該返回5。不得使用迴圈或遞迴

 def largest(fun: (Int) => Int, inputs: Seq[Int]) {
    inputs.map { x => (x, fun(x)) }.
      reduceOption((x, y) => if (x._1 > y._1) x else y).
      map { x => println(x._1) }
  }
  largest(x => x * x, (1 to 5))

7 要得到一個序列的對偶很容易,比如:val pairs = (1 to 10) zip (11 to 20)假定你想要對這個序列做某種操作,比如,給對偶中的值求和,但是你不能直接使用:pairs.map( + )函式 _ + _ 接受兩個Int作為引數,而不是(Int, Int)對偶。編寫函式adjustToPair,該函式接受一個型別為(Int, Int) => Int的函式作為引數,並返回一個等效的, 可以以對偶作為引數的函式。舉例來說就是:adjustToPair(_ * _)((6, 7))應得到42。然後用這個函式通過map計算出各個對偶的元素之和

  def ajustToPair(fun: (Int, Int) => Int) = (t: Tuple2[Int, Int]) => {
    fun(t._1, t._2)
  }
  println(ajustToPair(_ + _)(10, 4))

8 在12.8節中,你看到了用於兩組字串陣列的corresponds方法。做出一個對該方法的呼叫,讓它幫我們判斷某個字串數組裡的所有元素的長度是否和某個給定的整數陣列相對應

  val a = Array("a", "b", "ac")
  val b = Array(1, 1, 2)
  //對每個元素進行對比
  println(a.corresponds(b)(_.length == _))

9 不使用柯里化實現corresponds。然後嘗試從前一個練習的程式碼來呼叫。你遇到了什麼問題?
沒有柯里化則不能使用前一個練習裡的程式碼方式來呼叫

10 實現一個unless控制抽象,工作機制類似if,但條件是反過來的。第一個引數需要是換名呼叫的引數嗎?你需要柯里化嗎?

  def r(unless: => Boolean)(x: Int) {
    if (unless) {
      // 要執行的語句
    }
  }