Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScript、上達の瞬間
Search
sadnessOjisan
November 16, 2024
Technology
49
15k
TypeScript、上達の瞬間
tl;dr
焼肉
sadnessOjisan
November 16, 2024
Tweet
Share
More Decks by sadnessOjisan
See All by sadnessOjisan
PHPこそ OpenTelemetry が嬉しい
sadnessojisan
1
53
フロントエンド・オブザーバビリティを支える要素技術を学ぼう
sadnessojisan
2
480
疎通2024
sadnessojisan
5
1.3k
BasicBasic認証
sadnessojisan
5
3.9k
ISUCON入門以前_ISUNARABE_LT#1
sadnessojisan
19
5k
サーバーとは何かを理解して、コンテナ1つで実行しよう | PHPerKaigi2024
sadnessojisan
34
14k
Node.js v12 を使い続けていたのはなぁぜなぁぜ?
sadnessojisan
11
26k
かにさんタワーバトル
sadnessojisan
1
23k
現実世界におけるスキーマ設計の妥協
sadnessojisan
21
30k
Other Decks in Technology
See All in Technology
GitHub Actions의 다양한 기능 활용하기 - GitHub Universe '24 Recap
outsider
0
110
スパイクアクセス対策としての pitchfork 導入
riseshia
0
110
突き破って学ぶコンテナセキュリティ/container-breakout-cncj-lt
mochizuki875
6
1k
そろそろOn-Callの通知音について考えてみよう (PagerDuty編)
tk3fftk
1
320
知らない景色を見に行こう チャンスを掴んだら道が開けたマネジメントの旅 / Into the unknown~My management journey~
kakehashi
6
910
A/Aテストにおけるサンプルサイズ/japanr2024
nikkei_engineer_recruiting
1
360
開発者向けツールを魔改造してセキュリティ診断ツールを作っている話 - 第1回 セキュリティ若手の会 LT
pizzacat83
0
320
GeminiとUnityで実現するインタラクティブアート
hokkey621
0
540
ARRが3年で10倍になったプロダクト開発とAI活用の軌跡
akiroom
0
220
EthernetベースのGPUクラスタ導入による学びと展望
lycorptech_jp
PRO
0
530
[GDG DevFest Bangkok 2024] - The Future of Retail E-commerce with Gemini AI
punsiriboo
0
290
GAS × Discord bot × Gemini で作ったさいきょーの情報収集ツール
ysknsid25
1
650
Featured
See All Featured
Documentation Writing (for coders)
carmenintech
65
4.5k
For a Future-Friendly Web
brad_frost
175
9.4k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
24k
Statistics for Hackers
jakevdp
796
220k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
It's Worth the Effort
3n
183
27k
Fireside Chat
paigeccino
34
3.1k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
169
50k
How STYLIGHT went responsive
nonsquared
95
5.2k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
29
2k
Transcript
TypeScript 上達の瞬間 TSKaigi KANSAI @sadnessOjisan 💪
tl;dr • 私はCS未履修&&異業種コンバートでフロントエンドエンジニアから始めた 身です。 • チートのような知識を手に入れることで戦力として働けるようになりました ◦ 型に関する、学問寄りの知識を手に入れて急に伸びました ◦ 別言語での常識や失敗談という知識を手に入れて急に伸びました
• これらの独学は正直厳しかったので、学び方が重要と感じました
None
注意:あくまでも僕のケース この発表は、汎用的な学びの指針となるような発表ではないです 最近は本なども出ているので、まずはそういうのを読むと良いです ただ、この発表は皆さんの理解の穴を埋めるものにはなるかもしれません
関西と私 思い出のボウリング場
TypeScript と私 実は、あまり興味がないです。ほんとに。 バズってる二次、三次情報を読んでいます Issue を追ったり、自分の言葉で説明できる人はすごいと思います
そんな僕でもTSを 書けるようになる方法
詳しい人に手取り足取り教えてもらう
終 制作・著作 sadnessOjisan
自分のTypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からないよ〜〜〜 2. TypeScript の恩恵を引き出す方法が分からないよ〜〜〜 3.
実用・運用に乗せる方法が分からないよ〜〜〜
TypeScript、 どうやって勉強しました?
正攻法てきなのなくね?
TypeScriptを体系的に学ぼう!
体系?
IMO・要議論・要出典 そもそも TypeScript 自体に体系なんてものはなくて、 綺麗な学び方ってそもそもできない。 だって、「あったら嬉しい」という機能を継ぎ足して 進化し続けている言語じゃん
手探りで TypeScript を書く日々 (※正確には flowtype でしたが...)
None
この概念が関係しそうだけ ど、理由が分からなくて繋が りがあるのか分からない...
CSすごい博士 hoge 言語にはこの機能があるので、TSでも こういう機能があるはず hoge言語ではこのように型を使いこなすとう まくいくので、TSでも取り入れよう プログラム言語や型の理論ではこういう教え があるので、それを適用しよう
最初から地図の全てが見えている CSすごい博士
None
毎日プロに手取り足取りをしてもらって 壁を乗り越えられた。
壁を乗り越えられたのは運ではないか!
うん!!!!!!!
分かったこと
最初に知っておくだけで、 成長効率が段違いになるチート知識が 存在する
体系はないが、なにかしらの理論と何か しらのプラクティスはあり、それを知る のが学習の大きな手助けになる
TSのボトムアップな勉強では到達でき ない世界があり、TSの外側の知識を使 うとそれが見えてくる
None
自分のTypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からないよ〜〜〜 2. TypeScript の恩恵を引き出す方法が分からないよ〜〜〜 3.
実用・運用に乗せる方法が分からないよ〜〜〜
なぜ TypeScript が必要なのか • JavaScript でよくね? • テストでよくね? • Lintでよくね?
• assertionでよくね?
Twitterに書いたら 怒られました
ランタイムエラーを踏みまくれば 必要性が理解できる
ランタイムエラーへのassertionが めんどくさくなると、 必要性が理解できる
愚者は経験に学び、 賢者は歴史に学ぶ
プログラムを検証する学問の全体を知る • 形式手法 • 軽量形式手法の一つとして型システム • 型: 値の分類 • プログラムを実行することなく、プログラムがある種の振る舞いを起こさな
いことを保証する
色々な検証方法がある中で、 型検査に焦点を当てる
MinCaml の存在を教わる • 東京大学での CPU 実験で使わ れる教材の存在を教えてもらう • プロセッサとコンパイラを実験 する課題の中で、OCaml
で OCaml を実装する場面がある らしい • 教材が一般公開されていて僕た ちも遊べる • https://esumii.github.io/min- caml/
MinCaml で学べること プログラミング言語が動く仕組みを学べる 字句解析 構文解析 型検査 最適化 アセンブリの 出力
型検査 • 教科書的には項や変数を定義し、型推論の規則を定義する。 • 規則に従って、型環境を記録に使いながら、推論アルゴリズムを適用させて いく。 • 型注釈がなくても与えられた状況から逆算して型を決定する。
MinCaml で型検査を作ってみて • 型検査以外にも、そもそもプログラミング言語のソースコードがどうやって 実行されるのかが学べることが大きな財産 • 型検査の正体がプログラムであることを知る。(魔法じゃなかった!) • 型検査というプログラムによって、型システムが持つ機能を充実させられる という嗅覚を得る
• TypeScriptが如何に型破りであり、強力であり、柔軟であることを知る (MinCaml のやり方と全然違うことに後から気づき、MinCamlやらなくてよ かったことを学ぶ <- 逆説的かもしれないがめちゃくちゃ大事な経験)
挫折したら...
似たような教材は他にもあるので、 食いつまむと理解できるかもしれない
MinCaml 以外の選択肢 字句解析 構文解析 型検査 最適化 アセンブリの 出力 Go言語でつくるインタプリタ •
MinCaml の最初の壁の構文解析ま でがかなり丁寧 • MinCamlではパーサージェネレー タを使うが、こちらは手書きする • つまり、ナイーブで分かりやすい Goで学ぶはインタプリタ形式 なのでアセンブリは出力しな い。コンパイラ本もあるらし い
MinCaml 以外の選択肢 字句解析 構文解析 型検査 最適化 アセンブリの 出力 TaPL •
項や規則の定義をして、それを実 際に実装する課題があり、理論と 実装の橋渡しが見えてくる • 型システムにいろんな機能を増や していく進み方で学べる • 挫折するが、輪読会などに行くと 学べる(tapl.ts)
MinCaml 以外の選択肢 字句解析 構文解析 型検査 最適化 アセンブリの 出力 ゼロから学ぶRust •
デバッガやシェルを実装させるどう考えても入門 書ではない入門書 • RustでRustのサブセットを実装する章がある • Rustはアフィン型やライフタイムという機能が あり、変数の消費を型で検査できる(1度使うと 使えなくなる) • 型の世界でライフタイムを表現し、HM型推論を 実装する演習を通して、型検査に独自機能を足す と言うことが学べる
TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない a. TSなしでコードを書いてみてランタイムエラーをたくさん踏むと欲しくなる b. TSが保証しているようなことをテストなどで担保しようとすると、めんどくさくなって欲し
くなる c. 形式手法など学問として存在している分野を学ぶと、トップダウンに理由を人に説明できる ようになる 2. TypeScript の恩恵を引き出す方法が分からない 3. 実用・運用に乗せる方法が分からない
TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない a. TSなしでコードを書いてみてランタイムエラーをたくさん踏むと欲しくなる b. TSが保証しているようなことをテストなどで担保しようとすると、めんどくさくなって欲し
くなる c. 形式手法など学問として存在している分野を学ぶ 2. TypeScript の恩恵を引き出す方法が分からない 3. 実用・運用に乗せる方法が分からない
別言語のプラクティスを学ぶ • F# ではこうする、OCamlではこうする • 型と値、コンパイラがあたりまえにある言語はこう解釈される • 型の制約を強める恩恵を知る
型と値の違いを意識する • 型と値の違いを意識する ◦ TSのtypeofとJSのtypeofを使うのが良い訓練 • JSエコシステムにおけるコンパイルとは何かビルドとは何か ◦ FlowやTSをビルドすると、型が消える ◦
tsconfig の lib の中身を差し替えて、生成されるコードを見比べる ◦ @babel/plugin-transform-typescript を読む
babel/plugin-transform-typescript https://babeljs.io/docs/babel-plugin-transform-typescript
型の上下関係を知り、any と向き合う • TS使い始め: any 使って型推論を通すぜうぇーい • 実行時エラー: もしかして any
って悪いのか? • Twitterでは: any 撲滅! • 学び: any ってダメなのかも • 冷静になって: そもそも any ってなんですか? 後に引き継いだ同僚が600箇所の エラーを直すことになる。 (本当にごめんなさい)
型の上下関係 • 型の関係は supertype, subtype という上下関係で表現できる • 何でも受け入れる型: unknown •
何でも受け入れない型: never • (上下関係の外側で) 両方の性質を持つ: any unknown never
構造的部分型 • 「狭い型」と「広い型」 • 狭い(厳しい)・広い(緩い) を構造で判断 • 緩い側に厳しい側は代入できる • サブタイプはスーパータイプに
代入できる
変性 • Animal と Human というクラスがある • サブタイプはスーパータイプに代入できる • Animal
animal = new Human() はできる • Animal[] animals = new Human[2] はでき るのか? • P1 が P2 のサブタイプである ⇒ P1[] が P2[] のサブタイプである? • Java でよく言われていた問題らしい is-a 動物 (という概念)
変性 • 共変: ある型 A が型 B のサブタイプであるとき、Container<A> が Container<B>
のサブタイプとして扱える • 反変: A が B のサブタイプのとき、Handler<B> が Handler<A> のサブタイ プとして扱える • 他にも「共変かつ反変」や「共変でも反変でもない」というパターンも [🙀, 😱, 🙀]
TypeScript の変性はどうなのか • 配列は共変 • Javaと同じ問題を踏み抜いている! • animals である [🙀,
🙀, 🙀]を humans[😱, 😱, 😱]になるように破壊しても型検査が怒 らない • 何が問題か -> 配列を代入しても参照がコ ピーされるだけ。animalsの要素を入れ替え ると、humansの要素も書き換わり、human 専用メソッドを呼び出そうとすると、ラン タイムエラー • と言う理由で FlowType を薦められていた 過去がある https://qiita.com/na-o-ys/items/aa56d678cdf0de2bdd79
Opaque • TypeScript では userId👦 と ramenId🍜 を区別できない • 構造的型付けでは、string
という同じ構造 • flowtype にはそれらを区別できる opaque という機能がある ◦ https://flow.org/en/docs/types/opaque-types/
構造が違う型を無理やり定義する • type UserId = string & {__userId: never}; •
type RamenId = string & {__ramenId: never};
型の上下関係と代入についてのまとめ • any は何でも代入できるし、何にでも代入される • いい加減な代入でランタイムエラー • 変性によっていい加減な代入ができてしまうこともある • 構造的部分型に起因する型の分類の難しさは、Opaqueで守れる
型の制約を強めるには • 別言語プラクティスとして制約は強いほど強いほど良いらしい • どのようにしたら強められるかという意識を常に持とう ◦ never ◦ narrowing ◦
判別共用体
exhaustive check • if や switch で分岐を全てやり切った後 は never になる
• else 節や default 節で never かどうか を検査するようにすれば、分岐漏れをコ ンパイル時に気づける https://typescript-jp.gitbook.io/deep-dive/t ype-system/discriminated-unions
判別共用体を作る APIアクセスした結果をコンポーネントに出す状況を考える アクセス中は、ローダー、成功したら結果、失敗したらメッセージを出 したい アクセス中はデータもエラーも値には出てこないことを表現
判別共用体を作る ローディング中だけど、 データも存在しているという解釈もできてしまう
判別共用体を作る 真偽値や存在チェックをすることで、型が絞り込まれいくような、 定義の方法 F#でよくされるプラクティスらしい
TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない 2. TypeScript の恩恵を引き出す方法が分からない a.
別言語のプラクティスや設計ミスを知る b. 自分が教えてもらったのは、Java、F#、OCaml 3. 実用・運用に乗せる方法が分からない
TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない 2. TypeScript の恩恵を引き出す方法が分からない 3.
実用・運用に乗せる方法が分からない
ビルドを通せない • Error Cause を使いたい • Top Level Await を使いたい
• JSON を import したい • import するときの拡張子には何を選んだらいいか分からない
tsc --init
tsc --init 物足りない
ErrorCause 独自エラーで投げ直したいけど、元のエラーの情報も保持した い!
ErrorCause https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
ErrorCause https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error/cause 便利機能を使おうとすると ビルドエラー
オプションを使いこなす • target: どのバージョンのJSに落とし込むか • lib: targetがサポートしていない機能を実装するためのポリフィルを実装に 埋め込んでくれる(Promise, Array.prototype.hoge, …
• module: cjs, esm などのモジュール形式。TLA は ESM じゃないと動かない など、cjs だと同期的という制約があったりしてこのオプションをいじらな いとビルドできないものがある • esModuleIntertop: 使うライブラリや既存コードによっては cjs との互換性 を意識しないとビルドできなくなる • moduleResolution: ビルドツールが前提とする方法によって切り替える必要 が出てくる
ECMAScript それ自体を知る • ビルドに関するエラーの8割はモジュールに対しる不理解によるもの(当人 比) • モジュールとは何かを人に説明できるようになると良さそう • IMO: 訓練として
Jest と Vitest の比較などやってみると良さそう • (ちなみに僕は自身ないです)
TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない 2. TypeScript の恩恵を引き出す方法が分からない 3.
実用・運用に乗せる方法が分からない a. ビルドできない理由の6割はモジュールに対する理解だと思うので、ECMAScript そのもの を勉強する b. ECMAScript 仕様輪読会 などの勉強会に参加すると良いと思う。 優しい人が教えてくれるはず🟢
TSを使うなら、これで十分!?
複雑な型パズルを解けるようになりそう なエッセンスはどこにもないが?
持論 型パズルなんて解く必要がない。アプリケーション開発にお いて、呼び出し側は Specific なので汎用性を意識した推論 をさせる必要が生まれない。最悪 as でも any でも使っとけ
持論 型パズルなんて解く必要がない。アプリケーション開発にお いて、呼び出し側は Specific なので汎用性を意識した推論 をさせる必要が生まれない。最悪 as でも any でも使っとけ
切り抜くなよ!
アプリケーションをライブラリを 作るように作る場合は必要😢
アプリケーションをライブラ リのように作ると言う表現、 uhyoさんが昔いってた気がす るんだけど見つけられず
アプリケーションをライブラリを 作るように作らないといけない状況 • チーム全体、もしくはチームの垣根を超えて生産性に責任を持つ場合 • レイヤードな設計をちゃんとしたい場合 • インターフェースにこだわると自然にそうなっていってしまうかも
もしかして、 型パズルを解けると出世できる!?
もしかして、 型パズルを解けると出世できる!? 俺も出世するぞ!!!
型パズル力を鍛えるためには • 巷のライブラリを読む • ひたすら type-challenges を解く • そういうのが得意な人にペアプロしてもらう
初級すら解けないよ〜😢
勝ちパターンを覚えよう&見つけよう
気づいたらライブラリを 作れるようになる
ライブラリに潜むぎょっとする機能 • ジェネリクス • extends ◦ 型パラメータの extends ◦ ?
の前の extends • keyof • ? • infer • in ギョッ
勝ちパターン • 当てはまる型を逆算する→ジェネリクス, infer • 型の制約→extends • 型の分岐→extends, ?(Conditional Type)
• 繰り返し→in(Mapped Types), 再帰
None
None
MyPick<{hoge: number; fuga: string; piyo: number}, “hoge” | “fuga””> の結果を、{hoge:
number; fuga: string } にしたい。 MyPick<A, B> で呼ぶとして、UnionTypeになるB は オブジェクトA のキーで構成されないといけない 制約の extends, キーを抽出する keyof を使う
MyPick<{hoge: number; fuga: string; piyo: number}, “hoge” | “fuga””> の結果を、{hoge:
number; fuga: string } にしたい。 MyPick<A, B> で呼ぶとして、A からキーBを構成する要素で、 オブジェクトを抽出する操作を繰り返したい 繰り返しの in を使う
MyPick<{hoge: number; fuga: string; piyo: number}, “hoge” | “fuga””> の結果を、{hoge:
number; fuga: string } にしたい。 MyPick<A, B> で呼ぶとして、in で B から hoge と fuga が抽出されて繰り返されるので、A から その key に該当する要素を繰り返しで抽出されるように [key in K]: T[key] とする
None
None
First<T>の結果を、T[0] にしたい。 T は配列であることを保証したい 制約の extends を使う、要素は何でも良いので any[]
配列であることが保証されるのであれば、空配列でなければ 0 番目には必ずアクセスできる 空配列かどうかを判断したい 分岐の extends ?、ありえないことを表す never を使う
注: Promise の入れ子 もサポートする
https://github.com/type-challenges/type-challenges/issues/24969
https://github.com/type-challenges/type-challenges/issues/24969 Promise<U> から U を抽出したい Promise<Promise<U>> から U を抽出したい T
は Promise であるべきなので、extends PromiseLike<any> Promise の入れ子を表現できていないが、入れ子の段階で繰り返しが必要であることと、 Collection(配列やオブジェクト)が対象でないことから Mapped Types を使えなさそうで、 再帰の可能性を視野に入れる。繰り返されることを考えると1重のPromiseで済みそうと予想
https://github.com/type-challenges/type-challenges/issues/24969 Promise<U> から U を抽出したい マッチした型を抽出するので infer の出番
https://github.com/type-challenges/type-challenges/issues/24969 U が Promise なら二重のPromiseなので、もう一度 infer を適用したい。 再帰で MyAwaited を呼び出すか判定したいので
PromiseLike かどうかを調べる 分岐の extends
https://github.com/type-challenges/type-challenges/issues/24969 これ以上 Promise で包まれていない時に再帰は停止する
その他よく使うパターン • [number] • [U, ...T] • union distribution
実務で出番ある?
アプリケーションをライブラリを 作るように作らないといけない状況 • チーム全体、もしくはチームの垣根を超えて生産性に責任を持つ場合 • レイヤードな設計を徹底する場合
• ビジネスの都合上、あるフォーマットや構造に従うデータを扱わないといけ ない • その構造の変換を扱う処理をするのならば、ビジネス知識を反映した便利な 関数と型を作らないといけない • フォーマットの構造に合わせて、extends で分岐させつつ型を作る •
ex) JSON Schema to TS (https://github.com/type-challenges/type-challenges/blob/main/quest ions/26401-medium-json-schema-to-typescript/README.md)
汎用的な何かを作りたいなら 分岐と繰り返しは必須 • 全てのパターンを分岐で網羅し尽くす: conditional types • 規則を見つけて、繰り返しで適用する: mapped types,
再帰
汎用的な何かを作りたいなら 分岐と繰り返しは必須 • 全てのパターンを分岐で網羅し尽くす: conditional types • 規則を見つけて、繰り返しで適用する: mapped types,
再帰 チューリング完全
https://github.com/type-challenges/type-challenges/blob/main/README.ja.md
None
汎用的な何かを作りたいなら 分岐と繰り返しは必須 • 全てのパターンを分岐で網羅し尽くす: conditional types • 規則を見つけて、繰り返しで適用する: mapped types,
再帰 というか型の世界に書い ていたのはもはや普通の プログラム!
余談: 感動したパターン
自分でトップダウンな知識を 手に入れに行く
強く静的に型付けられた 関数型言語から学ぶ • 「強く静的に型づけられた関数型言語をやってみると新しい視点が手に入る よ」 • OCaml, Rust, Haskell, Scala
を勉強する ◦ けど、難しすぎて独学はできないのでこれも手取り足取り教わった... 今思えば、TSにおける上達のコツのほとんどは、これらの言語を使って いると当たり前に身についていたものな気がしている
別言語でのプラクティスを知っているだ けで、良いTSのコードが書ける
当然、エコシステムも黙っちゃあいない
強く静的に型付けられた言語にある概念 を持ち込んでいるライブラリの例 • fp-ts (https://github.com/gcanti/fp-ts) ◦ 名前の通りのことを実現するためのあれこれ集 • option-t(https://github.com/option-t/option-t) ◦
Result, Optional を持ち込む。Rust と同じIFになっているのが良い • monocle.ts(https://github.com/gcanti/monocle-ts) ◦ Scala に同名のライブラリがありそれのTS実装。Lens というデータ構造を使って、 immer.js がしていることを実現する
Result 型の流行 • try catch をし忘れる, エラーハンドリ ングのし忘れを型検査で防ぎたい • 成功失敗を表現するオブジェクトで包
めば良いが、呼び出す側が毎回 Result を解かないといけないのがめんどくさ い • Result という文脈を保ったまま計算す る方法を考える めんどくさい
文脈とは何か • 失敗するかもしれない: Result<Data, Error> • 空かもしれない: Optional<Data> • 結果が複数かもしれない:
List<Data>
文脈は型を引数に取る • Result, Option, List は bind(>>=) や map といった共通機能を持ち、文脈
を他の文脈と組み合わせるためのインターフェースとなる • m a … 文脈m に包まれた a • (>>=) :: m a -> (a -> m b) -> m b (※mは文脈) bind 演算子と呼ぶことを知らなくて、ググれ なくて困った思い出
型注釈から意味を読み取る • m: 文脈(Resultなど • m a -> (a ->
m b) -> m b 👀
型注釈から意味を読み取る • m a -> (a -> m b) ->
m b 👀 👀 👀 じ〜〜〜〜
型注釈から意味を読み取る • m a -> (a -> m b) ->
m b • 文脈に包まれた a を、a を引数にとって文脈に包まれた b を返すに渡すと、 文脈に包まれた b を返す • 文脈の中身が a から b に入れ替わっている • 文脈を保ったままの計算ができる • 文脈を一回解いて、関数を適用して、文脈で包みなしてくれる • どこかで見覚えが... -> flatMap • [1, 2, 3].flatMap(el => [el]) 👉 [1, 2, 3]
意味を読み取れると不適切な使われ方に も気づける • 失敗を表現する Result は、フォームの入力 エラー管理に使えそう? • m a
-> (a -> m b) -> m b • Result<Data, Input1> -> (Input1 -> Result <Data, Input2>) • Input1 のエラー内容を忘れてしまっている • 入力が複数のものに Result は適さない ◦ Validated という構造で解決できる(Scala) https://blog.ojisan.io/monad-applicative/
静的に型付けられた関数型言語 から得た学び • 型で文脈を表現するという手法 • 型注釈を見つめると、何を抽象化したものなのかが見えてくる
正直、初見だとハードルが高い
結局これも全部、詳しい人に 手取り足取り教えてもらっていた...
手取り足取り教わってみて • これを最初に押さえておくと上達が早まるチート知識が存在する • プログラミング言語の仕組みそのものと、強く静的に型づけられた関数型プ ログラミング言語から学べることが多い。(OCamlでOCaml作る講義がある大学裏山・・・) • TS特有の知識は、ライブラリを作るようにアプリケーションを作ろうとする と、学ばないといけない知識が炙り出される •
type-challenges がトレーニングとして良く、勝ちパターンを知ると急激に 上達し、その状態でライブラリを読むと答え合わせになる • チート知識だけでも誰かから装着してもらえると効率が良い
手取り足取り教わるためには • 僕は運が良くおせっかいな人たちに手取り足取り教えてもらえた • が、運に恵まれるための努力はしていた。毎日コード書いて、自分でも情報 発信して、エンジニアの飲み会にはほぼ出かけて、焼肉を献上していた。 • 最近、エンジニア教育に関するツイートが各所で盛り上がっており、手取り 足取り教わろうとする姿勢を嫌う意見をよく目にする。 •
でも、僕は嫌いじゃないので、僕でよければ是非お声がけください。僕も誰 かの力になりたいです。(焼肉は不要です)