Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

関数型プログラミング攻略ガイド

 関数型プログラミング攻略ガイド

第四回関数型プログラミング(仮)の会

Kenichi SUZUKI

March 24, 2023
Tweet

More Decks by Kenichi SUZUKI

Other Decks in Programming

Transcript

  1. Finally, safely-extensible and efficient language-integrated query PEPM '16: Proceedings of

    the 2016 ACM SIGPLAN Workshop on Partial Evaluation and Program ManipulationJanuary 2016 Pages 37–48https://doi.org/10.1145/2847538.2847542 Multi-Stage Programming、そして脆弱性レジリエンス × Clean Architecture https://engineering.visional.inc/blog/212/scalamatsuri2020-interview-msp/ 脆弱性レジリエンスを高めるための Clean Architecture https://yamory.io/blog/architecting-for-resilience/ エンタープライズアジャイル開発における品質管理とセキュリティ対策をyamoryで考える https://yamory.connpass.com/event/198588/ Scala3でコードは爆速になるマルチステージプログラミングの考え方 https://logmi.jp/tech/articles/324146 Dotty ではじめるマルチステージプログラミング入門 https://www.youtube.com/watch?v=gpQHgcIIzFY From Tagless-Final to Typed-Final: Program Transformations in the Final Style https://speakerdeck.com/dcubeio/from-tagless-final-to-typed-final-program-transformations-in-the-final-style ContractS Tech Book Vol.1 第8章 型の力で高品質にドメインをモデリングする ー関数型DDDに向けてー. https://nextpublishing.jp/book/14565.html Publications 3
  2. • C/C++ • CPUレジスタ、省メモリプログラミング • Java、Spring Boot、JavaScript • オブジェクト指向 •

    独自フレームワーク、テーラリング 4 関数型プログラミングをいかにして学んだか • 関数型スタイル • OCaml、Haskell • (一般化)代数的データ型 • HOAS、tagless • モナド • fold, unfold • 自然とセキュアコーディング
  3. 8 イミュータブルなデータ 二階関数 データの構築&分解 関数合成 第一級関数&ラムダ 代数的データ型 パターンマッチ パラメータ多相 一般的な再帰

    型クラス、インスタンス、法則 低次の抽象化(Equal, Semigroup, Monoid 等) 参照透過性、完全性 高階関数 部分適用、カリー化、ポイントフリースタイル GADT 高階カインド型 ランクN型 Folds & Unfolds 高次の抽象化(圏, 関手, モナド) 基本的なOptics 効率的な永続データ構造 存在型 コンビネータを用いたEDSL Codata (Co)Recursion Schemes 一歩進んだOptics 双対的な抽象化(Comonad) モナドトランスフォーマー Freeモナド & Extensible Effects 関数型アーキテクチャ 一歩進んだファンクタ(Exponential, Profunctors, Contravariant) GADTs と Finally Tagless を用いたEDSL 一歩進んだモナド(Continuation, Logic) 型族、関数従属 High-Performance カインド多相 ジェネリックプログラミング 型レベルプログラミング 依存型、シングルトン型 圏論 グラフ簡約 Higher-Order Abstract Syntax 関数型言語のためのコンパイラ設計 Profunctor Optics 初級 上級 The Ladder of Functional Programming
  4. 9 イミュータブルなデータ 二階関数 データの構築&分解 関数合成 第一級関数&ラムダ 代数的データ型 パターンマッチ パラメータ多相 一般的な再帰

    型クラス、インスタンス、法則 低次の抽象化(Equal, Semigroup, Monoid 等) 参照透過性、完全性 高階関数 部分適用、カリー化、ポイントフリースタイル GADT 高階カインド型 ランクN型 Folds & Unfolds 高次の抽象化(圏, 関手, モナド) 基本的なOptics 効率的な永続データ構造 存在型 コンビネータを用いたEDSL Codata (Co)Recursion Schemes 一歩進んだOptics 双対的な抽象化(Comonad) モナドトランスフォーマー Freeモナド & Extensible Effects 関数型アーキテクチャ 一歩進んだファンクタ(Exponential, Profunctors, Contravariant) GADTs と Finally Tagless を用いたEDSL 一歩進んだモナド(Continuation, Logic) 型族、関数従属 High-Performance カインド多相 ジェネリックプログラミング 型レベルプログラミング 依存型、シングルトン型 圏論 グラフ簡約 Higher-Order Abstract Syntax 関数型言語のためのコンパイラ設計 Profunctor Optics 初級 上級 The Ladder of Functional Programming マイクロフレームワークのた めに利用 ドメインモデル・ユースケースを表 現するために利用 某プロダクトで実践
  5. 学習ステップ 15 • 第一級関数 • 関数適用・関数合成 • 基本のデータ型 • リスト、map,

    filter, fold • パラメータ多相(多相型) • 代数的データ型 • パターンマッチング • 高階関数 • 部分適用、カリー化、ポイント フリー • 再帰・帰納 • 効率性 • 無限リスト • banana split • 木構造 • 型クラス・インスタンス・法則 • モノイド、半群、Equal • モナドと純粋関数 • コルーチン • 継続、CPS • パーサーコンビネーター 副作用のコントロール力 関数による表現力 基礎
  6. 進め方 16 忘れる モチベー ション Step 0 Step 1 基礎

    Step 2 関数の表現力 Step 3 副作用のコントロール力
  7. Step 0: モチベーション • 精度の高い型を表現できる ◦ 取り扱う領域が適切になる(狭まる)=テスト範囲を小さくできる • 型の浸透 ◦

    影響範囲が特定しやすくなり、変更容易性が高まる • マイクロフレームワークをつくるのに良い 17
  8. Step 0: いったん忘れる • 意識しないと従来のプログラミングの習得スタイルにはまってしまう ◦ 条件分岐、ループ処理、モジュール・クラス・・・ • 関数型プログラミング言語のベース理論 ◦

    Haskell → System F ◦ OCaml → ML ◦ Scala3 → DOT 18 柳川 範之、為末 大. Unlearn(アンラーン) 人生100年時代の新しい「学び」. 日経BP、2022.
  9. Step 1: 基礎 • 代数的データ型とパターンマッチングが特に重要(個人的に) • 関数と集合 • 型は値の集合 ◦

    依存型が出てくるまではこの理解でOK • すべては関数(ラムダ計算) • 関数型の基本スタイルを学ぶ 19
  10. Step 1: 基礎 • 素直にOCamlで取り組むのが吉 • セットアップが面倒かも、、、 ◦ emacs +

    tuareg • 言語は非常にシンプルで覚えやすい • 数式は一切でてきません 26 授業資料 http://pllab.is.ocha.ac.jp/~asai/book-mov/
  11. Step 1: 基礎 • 理解を深めるためにプログラミング言語をつくる • 教材 ◦ 筑波大学 ソフトウェアサイエンス実験

    ◦ http://logic.cs.tsukuba.ac.jp/jikken/ 27 関数プログラミングをするということは、 関数型プログラム言語を知るということ おすすめ
  12. ミニ言語をつくる(メニュー) • セットアップ • 言語の構成要素 ◦ 構文(Syntax) ◦ 意味論(Semantics) ◦

    型付規則(Typing Rule) • 基本的なインタープリター ◦ 基本的な言語機能 ◦ 構文・意味論 • 型検査と型推論 ◦ 型システム • 簡単なコンパイラの作成 ◦ 抽象機械 28 e ::= x 変数 | let x = e in e let式 | let rec f x = e in e let-rec式 | fun x -> e 関数 | e e 関数適用 | true 真理値リテラル(定数) | false 真理値リテラル(定数) | if e then e else e if式 | n 自然数リテラル (n は自然数 0, 1, 2, ...) | - e 整数演算(符号の反転) | e + e 整数演算(足し算) | e * e 整数演算(かけ算) | e / e 整数演算(割り算) | e = e 等しさ(整数と真理値) | e > e 大小比較(整数) | e < e 大小比較(整数)
  13. Step 2: 表現力を高める • 慣れないうちは、ついつい手続き・破壊的操作に戻りがち • このフェーズで関数脳をつくる • 処理を関数として分割すると、品質担保しやすい ◦

    特に品質担保したいところは、全域関数として切り出す • 遅延評価、foldl,foldrの特性が理解できればひとまずOK 29 Graham Hutton. 1999. A tutorial on the universality and expressiveness of fold. おすすめ
  14. まとめ 33 • まず頭を空っぽにする • 関数型プログラミング言語として作られた言語で学ぶのが近道 • すべては関数(という気持ち) • 関数型プログラミングは実用的

    ◦ 学術的な側面が垣間見えるので、一部の人たちが趣味でやっているように見えてしまう かもしれませんが、高品質かつ高生産につくれる • 適用・導入する技術レベルは予め決めておいたほうが良い ◦ オンボーディングとセット
  15. 参考文献 • 柳川 範之、為末 大(2022). Unlearn(アンラーン) 人生100年時代の新しい「学び」. 日経BP. • 浅井

    健一(2007). プログラミングの基礎. サイエンス社. • Miran Lipovača著、田中英行/村主崇行 共訳(2012).すごいHaskellたのしく学ぼう!. オーム社. • 大川徳之(2018).関数プログラミング実践入門.技術評論社. • Benjamin C. Pierce著、住井 英二郎 監訳、遠藤 侑介、酒井 政裕、今井 敬吾、黒木 裕介、今井 宜洋、才川隆文、今井 健男 訳(2013). 型システム入門. オーム社. • Paul Chiusano、Rúnar Bjarnason 著、株式会社クイープ 訳(2015). Scala関数型デザイン&プログラミング. インプレス. • Noel Welsh、Dave Gurnell(2020). Scala with Cats. Underscore Consulting LLP. • RichardBird 著、山下伸夫 訳(2017). Haskellによる関数プログラミングの思考法. ドワンゴ. • Chris Okasaki 著、稲葉一浩、遠藤侑介 訳(2017). 純粋関数型データ構造. ドワンゴ. • 原啓介(2020). 集合・位相・圏. 講談社. • 鹿島 亮(2009).数理論理学. 朝倉書店. • David I. Spivak 著、川辺 治之 訳(2021). みんなの圏論. 共立出版. • Hutton, Graham & Meijer, Erik. (1996). Monadic Parser Combinators.Technical report NOTTCS-TR-96-4. Department of Computer Science, University of Nottingham. • Graham Hutton. (1999). A tutorial on the universality and expressiveness of fold. Journal of Functional Programming, 9(4), 355–372. • Philip Wadler. (1992). The essence of functional programming. In Proceedings of the 19th ACM SIGPLAN-SIGACT symposium on Principles of programming languages (POPL '92). Association for Computing Machinery, New York, NY, USA, 1–14. • Meijer, E., Fokkinga, M., Paterson, R. (1991). Functional programming with bananas, lenses, envelopes and barbed wire. In: Hughes, J. (eds) Functional Programming Languages and Computer Architecture. FPCA 1991. Lecture Notes in Computer Science, vol 523. Springer, Berlin, Heidelberg. • 浅井 健一(2011). shift/reset プログラミング入門. • 亀山幸義、海野広志(2017). 離散構造. https://www.cs.tsukuba.ac.jp/~kam/lecture/discrete2017/ (2023年アクセス) • 住井 英二郎(2005). ラムダ計算入門. https://www.kb.ecei.tohoku.ac.jp/~sumii/class/keisanki-software-kougaku-2005/lambda.pdf(2023年アクセス) • 亀山幸義(2013). ソフトウェアサイエンス実験 関数プログラミング. https://www.logic.cs.tsukuba.ac.jp/jikken/(2023年アクセス) 34