技術をかじる猫

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

Scala 関数型デザイン&プログラミング:Exercize3.14-15

相変わらず教科書はこれ。

進みは遅いが書かないと覚えなさそうだったので書く。

Exercise3.14

foldLeft or foldRight を使って、append 作れ

  def append[A](as: List[A], a: A): List[A] =
    foldRight(as, apply(a))((a, b) => Cons(a, b))

// printRec(List.append(List(1,2,3,4), 5))

って書いたら、模範解答はリストの結合だったという…
append つったら要素追加でしょうよ(;;

fpinscala/List.scala at master · fpinscala/fpinscala · GitHub

作り直し

  def append[A](as: List[A], a: List[A]): List[A] =
    foldRight(as, a)((a, b) => Cons(a, b))

// List.append(List(1,2,3,4), List(5, 6, 7))

Exercise 3.15

複数のリストを結合する関数を作れ

  def flatten[A](as: List[A]*): List[A] = {
    def flatten(head: List[A], tail: Seq[List[A]]): List[A] = {
      tail match {
        case t if t.isEmpty => head
        case t              => flatten(foldRight(head, t.head)((a, b) => Cons(a, b)), t.tail)
      }
    }
    as match {
      case a if a.isEmpty => Nil
      case a if a.size == 1 => a.head
      case a => flatten(a.head, a.tail)
    }
  }

// こうですか?わかりません
// printRec(List.flatten(
//    List(1,2,3), List(4,5,6), List(7,8,9)
// ))

仕様は多分満たしてるんだけど、実行効率がなぁ?
なんか違う気がしてきた。

fpinscala/List.scala at master · fpinscala/fpinscala · GitHub

やっぱりー(;;
なんかシグネチャ固定化して欲しいです。割と真面目に。

気を取り直してシグネチャから実装…ってこうとしか思い浮かばんから!

def concat[A](as: List[List[A]]): List[A] = foldRight(as, Nil: List[A])(append)