by shigemk2

当面は技術的なことしか書かない

予習メモ #functional_shibuya

3 関数型プログラミングのデータ構造

随時更新するかもしれません。

3.4.1 リストを扱うその他の関数

練習問題が多い。問題の内容はzipWithとかfilterとかの再実装。一旦コードはこっちにまとめた。

github.com

この本ではコンパニオンオブジェクトListを実装しているが、Scalaの標準ライブラリにもListが存在する。

その他のListのメソッドはこちらも参照のこと。

www.scala-lang.org

3.4.2 より単純なコンポーネントからリスト関数を組み立てるときの非効率性

Listの問題

  • 汎用的な関数を利用して関数に基づいて演算やアルゴリズムを表現できる
  • が、結果として得られる実装が必ずしも効率的ではない(短絡ロジックを実装しないと計算量がめんどうなことになる)

3.5 ツリー

  • Listは代数的データ型と呼ばれるものの1つ。
  • 代数的データ型は抽象データ型をあわらすために使用されることがある
  • 1つ以上のデータコンストラクタによって定義されるデータ型
  • コンストラクタはそれぞれ0個以上の引数を受け取る
  • データ型がそのデータコンストラクタの和
  • 各データコンストラクタがその引数の積
  • パターンマッチングを使って代数的データ型の要素をうまく操作できる

代数的データ型とカプセル化

  • 型の内部表現を公開するからカプセル化に違反しているという異論
  • ミュータブルじゃないから公開されていても問題ない gist.github.com

3.6 まとめ

  • 代数的データ型
  • パターンマッチング
  • 純粋関数型のデータ構造を実装する方法

4 例外を使わないエラー処理

例外をスローすることは副作用

  • 関数型プログラミングでは例外は使わないけど、プログラミングにおけるエラーの生成と処理はどうするのか
  • エラーを値として返す
  • エラー処理ロジックの一本化
  • Option型とEither型を独自実装する方法をとり、エラー処理について学ぶ。

4.1 例外の光と影

  • 例外で参照等価性は失われてしまう
  • 参照透過な式は参照先の式と置き換えることが可能で、この置き換えによって意味が失われないことを意味する
  • コンテキストへの依存をもたらすのはよくない
  • 例外は型安全ではない

検査例外

  • 呼び出し元は決まりきったコードだらけのボイラープレートとなる
  • 検査例外では高階関数と相性が悪い

4.2 例外に代わる手法

  • 部分関数(一部の入力に対して定義されない関数)

Double型の偽の値を返す

  • エラーが隠れて伝搬される可能性
  • 呼び出し元がボイラープレートになる可能性
  • 多相コードに適用できない
  • 特別なポリシーや呼び出し規則が呼び出し元に要求される

4.3 Optionデータ型

  • 問題への答えが常にあるとは限らないことを戻り値の型で表すことである

4.3.1 Option型の仕様パータン

部分関数はプログラミングの常連で、関数型プログラミングではこの部分性にOptionデータ型で対処するのが一般的。

4.3.2 Optionの合成、リフト、例外指向のAPIラッピング

通常の関数をリフトすれば、Optionに対応する関数にできる