技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Scala 関数型デザイン&プログラミング:Exercize2.2 - 2.5

引き続き勉強がてら Exercise をやってみる。

Exercise 2.2

お題:配列が任意の比較関数でソートされているか判定せよ
ただし、メソッドシグネチャdef isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean 固定。

…generic な高階関数なだけか…

object Exercise2_2 extends App {
  def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
    if (as.size < 2) {
      true
    } else {
      ordered(as.head, as.tail.head) &&
        isSorted(as.tail, ordered)
    }
  }

  def isOrdered(a: Int, b: Int) = a < b

  println(s"test 1 to 10 ordered ${isSorted((1 to 10).toArray, isOrdered)}")
  println(s"test 10 to 1 ordered ${isSorted((1 to 10).reverse.toArray, isOrdered)}")
}

まぁこれ位なら…

Exercise 2.3

お題:この関数を実装しろ

def curry[A, B, C](f: (A, B) => C): A => (B => C)

なんだ、ただのカレーか

object Exercise2_3 extends App {
  def curry[A, B, C](f: (A, B) => C): A => (B => C) = {
    def curried(a1: A) = (a2: B) => f(a1, a2)
    curried
  }

  def createFilledArray(i: Int, b: Boolean): Array[Boolean] = Array.fill(i)(b)

  val curried = curry(createFilledArray)
  val arr: Array[Boolean] = curried(10)(true)

  println(arr.toSeq)
}

Exercise 2.4

お題: curry の逆向きを行う、uncurryを作成せよ

object Exercise2_4 extends App {
  def uncurry[A, B, C](f: A => (B => C)): (A, B) => C = {
    def unc(a1: A, a2: B) = f(a1)(a2)
    unc
  }

  def createFilledArray(i: Int)(b: Boolean): Array[Boolean] = Array.fill(i)(b)

  val curried = uncurry(createFilledArray)
  val arr: Array[Boolean] = curried(10, true)

  println(arr.toSeq)
}

Exercise 2.5

お題:二つの関数を合成する高階関数を作成せよ。

object Exercise2_5 extends App {
  def compose[A, B, C](f1: B => C, f2: A => B): A => C = {
    def com(v: A) = f1(f2(v))
    com
  }

  def toStr(d: Double) = d.toString
  def toDouble(i: Int) = i.toDouble

  println(compose(toStr, toDouble)(65535).getClass)
}

末尾再起に比べたら緩い…。