Ladder of Functional Programming 〜関数型プログラミングのレベル分け〜

[LambdaConf](http://lambdaconf.us/)が[ツイート](https://twitter.com/lambda_conf/status/803695008100466688)にて関数型プログラミングのレベル分けを発表していました。今後[LambdaConfから発信される発表](https://www.youtube.com/channel/UCEtohQeDqMSebi2yvLMUItg)にはこのレベルが表記され, 自分のレベルにあったコンテンツが探しやすくなるようです。このレベル分けはプログラマの優劣を付けるようなものではなく, 広く深い関数型プログラミングの世界で自分が今どのレベルにいるのかを適切に理解し次にどこに向かうべきなのかを知るのにたいへん役に立つものだと思います。 表を眺めてみると関数型プログラミングというよりかはHaskellのレベル分けのような印象も受けますが、広く知られるべきだと思ったので翻訳してみました。僕が未熟でトンチンカンな訳をしている箇所もあると思うので、何か見つけた場合は遠慮なくコメントや編集リクエストをお願いします :pray: 

Ladder of Functional Programming
---------------------------------

[![CydL5EYUsAAI-61.jpg](https://qiita-image-store.s3.amazonaws.com/0/17134/6c420505-6f9d-0a42-2620-017f97986470.jpeg)](http://lambdaconf.us/downloads/documents/lambdaconf_slfp.pdf)

LambdaConf Ladder of Functional Programming (LOFP) はエキスパートレベルの関数型プログラマーになるために開発者が習熟しなければならない様々な概念やスキルを並べて標準化したものです。LOFPはワークショップ、発表、プレゼン、本、授業をランク付けするのに使うことができるので、意欲あふれる関数型プログラマーはそれらの中からどの教材が自分に適しているのかをよく理解することができます。

### NOVICE
* **概念**
    * イミュータブルなデータ
    * 二階関数
    * データの構築＆分解
    * 関数合成
    * 第一級関数＆ラムダ
* **スキル**
    * 二階関数(map, filter, fold)をイミュータブルなデータ構造に対して使える
    * 値を分解して要素にアクセスすることができる
    * 存在しないかもしれないことを表すデータ型を使うことができる
    * 基本的な型シグニチャを読むことができる
    * 二階関数にラムダを渡すことができる

### ADVANCED BEGINNER
* **概念**
    * 代数的データ型
    * パターンマッチ
    * パラメータ多相
    * 一般的な再帰
    * 型クラス、インスタンス、法則
    * 低次の抽象化(Equal, Semigroup, Monoid 等)
    * 参照透過性、完全性
    * 高階関数
    * 部分適用、カリー化、ポイントフリースタイル
* **スキル**
    * null, 例外, 型キャストを使わずに問題が解ける
    * 再帰を使って再帰的データ構造の処理＆変換ができる
    * 関数型プログラミングを使って小さなプロジェクトを作ることができる
    * 具体的なモナドを使ってモナディックなコードが書ける
    * 独自のデータ型の型クラスのインスタンスが作れる
    * ビジネスドメインをADTを使ってモデル化できる
    * 関数を引数にしたり関数を返したりする関数を書ける
    * 非純粋なコードから純粋なコードを見つけ出し切り分けることができる
    * 不必要なラムダや名前付きパラメータを導入することを避けることができる

### COMPETENT
* **概念**
    * GADT
    * 高階カインド型
    * ランクN型
    * Folds & Unfolds
    * 高次の抽象化(圏, 関手, モナド)
    * 基本的なOptics
    * 効率的な永続データ構造
    * 存在型
    * コンビネータを用いたEDSL
* **スキル**
    * 関数型プログラミングを使って大きなプロジェクトを作ることができる
    * ジェネレータとプロパティを使ってテストコードが書ける
    * モナドを使って純粋関数的な方法で手続的なコードを書ける
    * 実問題を解くためによく使われる純粋関数的なライブラリを使うことが出来る
    * 決定的な計算を副作用を含む計算から分離することができる
    * 法則をみたす簡単な自作のモナドを作ることができる
    * 中規模なプロダクションのプロジェクトを作ることができる
    * Lens や Prism を使ってデータを操作することができる
    * 存在型を使って関係ないデータを隠蔽し型を単純にすることができる

### PROFICIENT
* **概念**
    * Codata
    * (Co)Recursion Schemes
    * 一歩進んだOptics
    * 双対的な抽象化(Comonad)
    * モナドトランスフォーマー
    * Freeモナド ＆ Extensible Effects
    * 関数型アーキテクチャ
    * 一歩進んだファンクタ(Exponential, Profunctors, Contravariant)
    * GADTs と Finally Tagless を用いたEDSL
    * 一歩進んだモナド(Continuation, Logic)
    * 型族、関数従属
* **スキル**
    * 最小限で十分なモナドトランスフォーマーのスタックを設計することができる
    * 並行、ストリーム処理のプログラムを書くことができる
    * テストで純粋関数的なモックを使うことができる
    * 異なる副作用を使いまわせる形にモデル化するために型クラスを使うことができる
    * 型のパターンを認識し、それを抽象化することができる
    * 新しい方法を取り入れた関数型のライブラリを使うことができる
    * 状態を操作するためにOpticsを使うことができる
    * 法則を満たすモナドトランスフォーマーを自分で作ることができる
    * 関心の分離のためにFreeモナド／Extensible Effectsを使うことができる
    * 不変条件を型レベルにエンコードすることができる
    * 安全なコードを書くために関数従属／型族を効果的に使うことができる

### EXPERT
* **概念**
    * High-Performance
    * カインド多相
    * ジェネリックプログラミング
    * 型レベルプログラミング
    * 依存型、シングルトン型
    * 圏論
    * グラフ簡約
    * Higher-Order Abstract Syntax
    * 関数型言語のためのコンパイラ設計
    * Profunctor Optics
* **スキル**
    * 広く使ってもらえるようなジェネリックで法則に適ったライブラリを作ることができる
    * equational reasoningを使って性質を手で示すことができる
    * 新しい関数型プログラミング言語を設計＆実装することができる
    * 新しい抽象化を法則とともに作ることができる
    * 確かな保証を元に分散システムを構築することができる
    * コードの性質を形式的に示すために証明系を使うことができる
    * 無効な状態を許さないライブラリを作ることができる
    * コンパイル時により多くの性質を証明するために依存型を使うことができる
    * 異なる概念の間の深い関係を理解している
    * 少しの犠牲で純粋関数的なコードをプロファイル、デバッグし最適化することができる

以上の翻訳は原本と同じライセンス[CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/)で公開されています。