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
EN
Uploaded by
Kazuyuki TAKASE
PDF, PPTX
4,033 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
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
by
Takuto Wada
PDF
マイクロにしすぎた結果がこれだよ!
by
mosa siru
PDF
ドメイン駆動設計のためのオブジェクト指向入門
by
増田 亨
PDF
Marp Tutorial
by
Rui Watanabe
PDF
オブジェクト指向できていますか?
by
Moriharu Ohzu
PDF
正しいものを正しく作る塾-設計コース
by
増田 亨
PDF
例外設計における大罪
by
Takuto Wada
PPTX
DockerコンテナでGitを使う
by
Kazuhiro Suga
SQLアンチパターン 幻の第26章「とりあえず削除フラグ」
by
Takuto Wada
マイクロにしすぎた結果がこれだよ!
by
mosa siru
ドメイン駆動設計のためのオブジェクト指向入門
by
増田 亨
Marp Tutorial
by
Rui Watanabe
オブジェクト指向できていますか?
by
Moriharu Ohzu
正しいものを正しく作る塾-設計コース
by
増田 亨
例外設計における大罪
by
Takuto Wada
DockerコンテナでGitを使う
by
Kazuhiro Suga
What's hot
PDF
インフラエンジニアの綺麗で優しい手順書の書き方
by
Shohei Koyama
PDF
何となく勉強した気分になれるパーサ入門
by
masayoshi takahashi
PDF
イミュータブルデータモデル(入門編)
by
Yoshitaka Kawashima
PPTX
イベント・ソーシングを知る
by
Shuhei Fujita
PPTX
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
by
Hiroshi Ito
PDF
IT系エンジニアのためのプレゼンテーション入門
by
Masahito Zembutsu
PDF
ADRという考えを取り入れてみて
by
infinite_loop
PPTX
SPAセキュリティ入門~PHP Conference Japan 2021
by
Hiroshi Tokumaru
PDF
ドメイン駆動設計 本格入門
by
増田 亨
PDF
デキるプログラマだけが知っているコードレビュー7つの秘訣
by
Masahiro Nishimi
PDF
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
by
Koichiro Matsuoka
PDF
ストリーム処理を支えるキューイングシステムの選び方
by
Yoshiyasu SAEKI
PDF
オントロジーとは?
by
Kouji Kozaki
PDF
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
by
増田 亨
PPTX
チャットコミュニケーションの問題と心理的安全性の課題 #EOF2019
by
Tokoroten Nakayama
PDF
Python におけるドメイン駆動設計(戦術面)の勘どころ
by
Junya Hayashi
PDF
PlaySQLAlchemy: SQLAlchemy入門
by
泰 増田
PDF
ワタシはSingletonがキライだ
by
Tetsuya Kaneuchi
PPTX
DXとかDevOpsとかのなんかいい感じのやつ 富士通TechLive
by
Tokoroten Nakayama
PDF
世界でいちばんわかりやすいドメイン駆動設計
by
増田 亨
インフラエンジニアの綺麗で優しい手順書の書き方
by
Shohei Koyama
何となく勉強した気分になれるパーサ入門
by
masayoshi takahashi
イミュータブルデータモデル(入門編)
by
Yoshitaka Kawashima
イベント・ソーシングを知る
by
Shuhei Fujita
データ履歴管理のためのテンポラルデータモデルとReladomoの紹介 #jjug_ccc #ccc_g3
by
Hiroshi Ito
IT系エンジニアのためのプレゼンテーション入門
by
Masahito Zembutsu
ADRという考えを取り入れてみて
by
infinite_loop
SPAセキュリティ入門~PHP Conference Japan 2021
by
Hiroshi Tokumaru
ドメイン駆動設計 本格入門
by
増田 亨
デキるプログラマだけが知っているコードレビュー7つの秘訣
by
Masahiro Nishimi
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
by
Koichiro Matsuoka
ストリーム処理を支えるキューイングシステムの選び方
by
Yoshiyasu SAEKI
オントロジーとは?
by
Kouji Kozaki
ドメインロジックに集中せよ 〜ドメイン駆動設計 powered by Spring
by
増田 亨
チャットコミュニケーションの問題と心理的安全性の課題 #EOF2019
by
Tokoroten Nakayama
Python におけるドメイン駆動設計(戦術面)の勘どころ
by
Junya Hayashi
PlaySQLAlchemy: SQLAlchemy入門
by
泰 増田
ワタシはSingletonがキライだ
by
Tetsuya Kaneuchi
DXとかDevOpsとかのなんかいい感じのやつ 富士通TechLive
by
Tokoroten Nakayama
世界でいちばんわかりやすいドメイン駆動設計
by
増田 亨
関数型プログラミングのデザインパターンひとめぐり
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