Download free for 30 days
Sign in
Upload
Language (EN)
Support
Business
Mobile
Social Media
Marketing
Technology
Art & Photos
Career
Design
Education
Presentations & Public Speaking
Government & Nonprofit
Healthcare
Internet
Law
Leadership & Management
Automotive
Engineering
Software
Recruiting & HR
Retail
Sales
Services
Science
Small Business & Entrepreneurship
Food
Environment
Economy & Finance
Data & Analytics
Investor Relations
Sports
Spiritual
News & Politics
Travel
Self Improvement
Real Estate
Entertainment & Humor
Health & Medicine
Devices & Hardware
Lifestyle
Change Language
Language
English
Español
Português
Français
Deutsche
Cancel
Save
Submit search
EN
Uploaded by
Kazuyuki TAKASE
PDF, PPTX
4,022 views
関数型プログラミングのデザインパターンひとめぐり
このスライドは、2021/11/27 に開催された「JSConf JP 2021」で発表したものです。
Engineering
◦
Read more
2
Save
Share
Embed
Embed presentation
Download
Download as PDF, PPTX
1
/ 15
2
/ 15
3
/ 15
4
/ 15
5
/ 15
Most read
6
/ 15
7
/ 15
Most read
8
/ 15
9
/ 15
10
/ 15
Most read
11
/ 15
12
/ 15
13
/ 15
14
/ 15
15
/ 15
More Related Content
PDF
例外設計における大罪
by
Takuto Wada
PDF
ドメイン駆動設計 失敗したことと成功したこと
by
BIGLOBE Inc.
ODP
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
by
pospome
PDF
Where狙いのキー、order by狙いのキー
by
yoku0825
PDF
マイクロにしすぎた結果がこれだよ!
by
mosa siru
PDF
ソーシャルゲームのためのデータベース設計
by
Yoshinori Matsunobu
PDF
Tackling Complexity
by
Yoshitaka Kawashima
PDF
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
by
Y Watanabe
例外設計における大罪
by
Takuto Wada
ドメイン駆動設計 失敗したことと成功したこと
by
BIGLOBE Inc.
Goのサーバサイド実装におけるレイヤ設計とレイヤ内実装について考える
by
pospome
Where狙いのキー、order by狙いのキー
by
yoku0825
マイクロにしすぎた結果がこれだよ!
by
mosa siru
ソーシャルゲームのためのデータベース設計
by
Yoshinori Matsunobu
Tackling Complexity
by
Yoshitaka Kawashima
ツール比較しながら語る O/RマッパーとDBマイグレーションの実際のところ
by
Y Watanabe
What's hot
PDF
Domain Modeling Made Functional (DevTernity 2022)
by
Scott Wlaschin
PDF
オブジェクト指向エクササイズのススメ
by
Yoji Kanno
PDF
強いて言えば「集約どう実装するのかな、を考える」な話
by
Yoshitaka Kawashima
PDF
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
by
shinjiigarashi
PDF
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
by
Takuto Wada
PDF
ドメイン駆動設計 本格入門
by
増田 亨
PDF
オブジェクト指向できていますか?
by
Moriharu Ohzu
PDF
イミュータブルデータモデルの極意
by
Yoshitaka Kawashima
PDF
PostgreSQLアンチパターン
by
Soudai Sone
PDF
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
by
Koichiro Matsuoka
PDF
イミュータブルデータモデル(入門編)
by
Yoshitaka Kawashima
PDF
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
by
Takuto Wada
PPTX
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
by
NTT DATA Technology & Innovation
PPTX
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
by
Ohyama Masanori
KEY
やはりお前らのMVCは間違っている
by
Koichi Tanaka
PDF
Akkaで分散システム入門
by
Shingo Omura
PDF
ゲーム開発者のための C++11/C++14
by
Ryo Suzuki
PPTX
async/await のしくみ
by
信之 岩永
PDF
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
by
Hiro H.
PDF
PostgreSQLの運用・監視にまつわるエトセトラ
by
NTT DATA OSS Professional Services
Domain Modeling Made Functional (DevTernity 2022)
by
Scott Wlaschin
オブジェクト指向エクササイズのススメ
by
Yoji Kanno
強いて言えば「集約どう実装するのかな、を考える」な話
by
Yoshitaka Kawashima
導入から 10 年、PHP の trait は滅びるべきなのか その適切な使いどころと弱点、将来について
by
shinjiigarashi
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
by
Takuto Wada
ドメイン駆動設計 本格入門
by
増田 亨
オブジェクト指向できていますか?
by
Moriharu Ohzu
イミュータブルデータモデルの極意
by
Yoshitaka Kawashima
PostgreSQLアンチパターン
by
Soudai Sone
DDDのモデリングとは何なのか、 そしてどうコードに落とすのか
by
Koichiro Matsuoka
イミュータブルデータモデル(入門編)
by
Yoshitaka Kawashima
SQLアンチパターン - 開発者を待ち受ける25の落とし穴 (拡大版)
by
Takuto Wada
Kubernetesでの性能解析 ~なんとなく遅いからの脱却~(Kubernetes Meetup Tokyo #33 発表資料)
by
NTT DATA Technology & Innovation
監査要件を有するシステムに対する PostgreSQL 導入の課題と可能性
by
Ohyama Masanori
やはりお前らのMVCは間違っている
by
Koichi Tanaka
Akkaで分散システム入門
by
Shingo Omura
ゲーム開発者のための C++11/C++14
by
Ryo Suzuki
async/await のしくみ
by
信之 岩永
Linuxにて複数のコマンドを並列実行(同時実行数の制限付き)
by
Hiro H.
PostgreSQLの運用・監視にまつわるエトセトラ
by
NTT DATA OSS Professional Services
関数型プログラミングのデザインパターンひとめぐり
1.
© Chatwork JSConf JP
2021 Chatwork 株式会社 CTO 室 / エンジニア採用広報 高瀬 和之 (@Guvalif) 関数型プログラミングの デザインパターンひとめぐり with Ramda.js
2.
© Chatwork ■ 概要
🗒 Haskell ライクな関数型プログラミングを JavaScript にて行えるようにするライブラリ "Ramda.js" を (一部) 例にして、 関数型プログラミングにおいて頻出のデザインパターンをご紹介します。 ■ 関数型プログラミングに対する私の立ち位置 - 良い設計を発見する ための、ベース知識として用いる - 安全な開発を実現する ための、勘所として用いる - これらは決してプログラミング言語に依存すること無く、 普遍的に応用可能 だと考える - つまり、ライトユーザーです (コワクナイヨ! 2 まえおき
3.
© Chatwork 3 純粋関数 -
関数型プログラミングの大原則 → 主役は "純粋関数" - 純粋関数とは? - 引数に同じ値を与えたら、常に同じ戻り値を返す関数のこと - なおかつ、副作用が存在しないもの - "参照透過" というキーワードで、ひとえに説明しても良い - なぜ純粋関数を用いるのか? - 副作用が存在しない ≒ 挙動が予測しやすい - 型システム を併用することで、予測可能性をさらに高める ことができる const add: (_0: number, _1: number) => number = (x, y) => x + y; const log: (_: string) => void = (s) => console.log(s); 純粋関数の例 (インプレイスな置き換えが可能) 純粋関数でない例 (外部から観測できない作用がある)
4.
© Chatwork 4 カリー化 -
"複数の引数を取る関数" と "単一の引数を取る関数" は、相互変換ができる - 理論的背景を知りたい方は ... → "積対象 指数対象 随伴" で Let's Google 🔍 - cf. 『圏論と Swift への応用』 by inamiy さん const add : (_0: number, _1: number) => number = (x, y) => x + y; const add_: (_0: number) => (_1: number) => number = (x) => (y) => x + y; // 使い方が異なるだけで、効果は変わらない add(1, 2) === add_(1)(2);
5.
© Chatwork 5 カリー化による設計上のメリット -
例) カリー化による環境の固定 - 同様に、Dependency Injection にも応用できる - ちなみに、Ramda.js では全ての関数が標準でカリー化 されている 🎉 const buildSendMessageRequest = ({ secret, roomId }: ChatworkEnv) => (body: string) => ({ method: 'POST', url: `https://api.chatwork.com/v2/rooms/${roomId}/messages`, headers: { 'X-ChatworkToken': secret, }, data: `body=${body}`, }); // builder: (body: string) => Request として、簡便に使いまわすことができる const builder = buildSendMessageRequest({ secret: 'XXXX', roomId: '123456789' });
6.
© Chatwork 6 副作用との付き合い方 -
"純粋関数が主役" という考え方より、副作用も観測可能にしたい ... - どうする? → 副作用をなるべくデータ型として表現する (≒ 作用を型で明示する) - 例) Tagged Union Type により、try - catch を用いずに異常系を表現する interface Left<T> { value: T; _tag: 'Left'; } interface Right<T> { value: T; _tag: 'Right'; } // 慣例的に、Left が異常系,Right が正常系を表す type Either<L, R> = Left<L> | Right<R>; function safeDiv( x: number, y: number, ): Either<Error, number> { if (y === 0) { return left(new Error('/ by 0 !')); } return right(x / y); } ファクトリ関数とする
7.
© Chatwork 7 作用を便利に扱うための演算群 -
慣例的に、ジェネリック関数の3つ組を考えることが多い - 理論的背景を知りたい方は ... → "計算効果 Monad" で Let's Google 🔍 - cf. 『Notions of Computation and Monads』 by Eugenio Moggi // Haskell では 'pure' という名で知られる // cf. https://ramdajs.com/docs/#of of: <T>(value: T) => M<T> // Haskell では 'fmap' という名で知られる // cf. https://ramdajs.com/docs/#map map: <A, B>(f: (_: A) => B) => (_: M<A>) => M<B> // Haskell では 'bind' という名で知られる // cf. https://ramdajs.com/docs/#chain chain: <A, B>(kf: (_: A) => M<B>) => (_: M<A>) => M<B>
8.
© Chatwork 8 各演算群の直感的な意味 -
例) M<_> を Promise<_> で置き換えると ... - ※ 厳密には、Promise だと良い性質を持たないので注意! // "値" を "作用のある値" に変換する (※ もっとも自明な変換を用いる) const of: <T>(value: T) => Promise<T> = (value) => Promise.resolve(value); // "関数" を "作用のある関数" に変換する const map: <A, B>(f: (_: A) => B) => (_: Promise<A>) => Promise<B> = (f) => (promise) => promise.then(f); // "途中で作用をもつ関数" を "作用のある関数" に変換する const chain: <A, B>(kf: (_: A) => Promise<B>) => (_: Promise<A>) => Promise<B> = // .then メソッドの性質から、map と実装が変わらない (ややつまらない実装) (kf) => (promise) => promise.then(kf);
9.
© Chatwork of の役割: "値"
から ... "作用のある値" への変換 map の役割: "関数" から ... "作用のある関数" への変換 chain の役割: "途中で作用をもつ関数" から ... "作用のある関数" への変換 map(f): (_: M<A>) => M<B> f: (_: A) => B 9 各演算群の直感的な意味 (図解版) X A B M<A> M<B> map M<X> of: (_: X) => M<X> M<A> M<B> chain(kf): (_: M<A>) => M<B> kf: (_: A) => M<B> A chain
10.
© Chatwork 10 ADT
と Catamorphism - Union Type や Tuple Type を (複合的に) 用いたデータ型を、ADT と呼ぶ - ADT = Argebraic Data Type の意 → 代数的データ型 - ADT に対しては、自然な分解と変換 を定義することができる → 代表例が Catamorphism - 理論的背景を知りたい方は ... → "F 始代数" で Let's Google 🔍 const either = <L, R, T>(lmap: (_: L) => T) => (rmap: (_: R) => T) => (m: Either<L, R>): T => { // 対称性を強調するために、それぞれの場合分けを明示的に記述 if (m._tag === 'Left') { return lmap(m.value); } if (m._tag === 'Right') { return rmap(m.value); } };
11.
© Chatwork 11 Catamorphism
の応用例 - 例) Either に対する、統一的なエラーハンドリング - ちなみに、配列に対する reduceRight も Catamorphism だったりする - いわゆる "畳み込み" と呼ばれる操作は、Catamorphism として一般化できる const lmap = (e: Error) => e.name; const rmap = (x: number) => `${x}`; const handler: (_: Either<Error, number>) => string = either(lmap)(rmap); // try - catch 方式と、大きく使い勝手が変わらない console.log(handler(safeDiv(N / M)));
12.
© Chatwork 12 複合的なユースケース
→ "ブラックジャック" の例 - Qiita に参考記事を掲載しているので、ぜひ一読してみてください 🗒 - cf. 『JavaScript で (なるべく) 関数型にブラックジャックを実装する』 by Guvalif ×
13.
© Chatwork 13 現実的なユースケース
in Chatwork → リリース基盤のバックエンド実装 - Ramda.js をフル活用して、CLI や CRON を実装しています 🗒 - 余談) 公式技術ブログに記事化したいと思い続けて、一年半が過ぎた 😇 const rejectEmptyEffect = R.ifElse( R.isEmpty, () => Promise.reject(new Error('スナップショットに含めるべきファイルが存在しません')), Promise.resolve.bind(Promise), ); const uploadFileEffect = createUploadFileEffect(s3Env, birdcageEnv); const uploadFileWithLoggingEffect = R.pipe( R.tap<File>((file) => console.log(`Uploading: ${file.name}`)), uploadFileEffect, );
14.
© Chatwork 14 まとめ -
関数型プログラミングの考え方には、実用上も便利 なものが多い 👌 - なおかつ、理論的背景 もしっかりしている 📖 - Haskell を使うのは大変でも、Ramda.js だったらライト に始められる 🚀 - 時間があったら取り扱いたかったトピック: - 合成可能な setter と getter の組,Lens - Applicative による Validation の一般化 - map も、filter も、reduce も自由自在,Transducer - (思い切って Session 枠を取りにいっても良かった感 🤔)
15.
© Chatwork 15 働くを もっと楽しく、 創造的に We
are Hiring !!! Chatwork 株式会社では、 フロントエンド,バックエンドのどちらでも、 関数型の考え方で設計にチャレンジしたい エンジニアを 募集🔗 しています 🙌
Download