Slide 1

Slide 1 text

TypeScript 上達の瞬間 TSKaigi KANSAI @sadnessOjisan 💪

Slide 2

Slide 2 text

tl;dr ● 私はCS未履修&&異業種コンバートでフロントエンドエンジニアから始めた 身です。 ● チートのような知識を手に入れることで戦力として働けるようになりました ○ 型に関する、学問寄りの知識を手に入れて急に伸びました ○ 別言語での常識や失敗談という知識を手に入れて急に伸びました ● これらの独学は正直厳しかったので、学び方が重要と感じました

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

注意:あくまでも僕のケース この発表は、汎用的な学びの指針となるような発表ではないです 最近は本なども出ているので、まずはそういうのを読むと良いです ただ、この発表は皆さんの理解の穴を埋めるものにはなるかもしれません

Slide 5

Slide 5 text

関西と私 思い出のボウリング場

Slide 6

Slide 6 text

TypeScript と私 実は、あまり興味がないです。ほんとに。 バズってる二次、三次情報を読んでいます Issue を追ったり、自分の言葉で説明できる人はすごいと思います

Slide 7

Slide 7 text

そんな僕でもTSを 書けるようになる方法

Slide 8

Slide 8 text

詳しい人に手取り足取り教えてもらう

Slide 9

Slide 9 text

終 制作・著作 sadnessOjisan

Slide 10

Slide 10 text

自分のTypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からないよ〜〜〜 2. TypeScript の恩恵を引き出す方法が分からないよ〜〜〜 3. 実用・運用に乗せる方法が分からないよ〜〜〜

Slide 11

Slide 11 text

TypeScript、 どうやって勉強しました?

Slide 12

Slide 12 text

正攻法てきなのなくね?

Slide 13

Slide 13 text

TypeScriptを体系的に学ぼう!

Slide 14

Slide 14 text

体系?

Slide 15

Slide 15 text

IMO・要議論・要出典 そもそも TypeScript 自体に体系なんてものはなくて、 綺麗な学び方ってそもそもできない。 だって、「あったら嬉しい」という機能を継ぎ足して 進化し続けている言語じゃん

Slide 16

Slide 16 text

手探りで TypeScript を書く日々 (※正確には flowtype でしたが...)

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

この概念が関係しそうだけ ど、理由が分からなくて繋が りがあるのか分からない...

Slide 19

Slide 19 text

CSすごい博士 hoge 言語にはこの機能があるので、TSでも こういう機能があるはず hoge言語ではこのように型を使いこなすとう まくいくので、TSでも取り入れよう プログラム言語や型の理論ではこういう教え があるので、それを適用しよう

Slide 20

Slide 20 text

最初から地図の全てが見えている CSすごい博士

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

毎日プロに手取り足取りをしてもらって 壁を乗り越えられた。

Slide 23

Slide 23 text

壁を乗り越えられたのは運ではないか!

Slide 24

Slide 24 text

うん!!!!!!!

Slide 25

Slide 25 text

分かったこと

Slide 26

Slide 26 text

最初に知っておくだけで、 成長効率が段違いになるチート知識が 存在する

Slide 27

Slide 27 text

体系はないが、なにかしらの理論と何か しらのプラクティスはあり、それを知る のが学習の大きな手助けになる

Slide 28

Slide 28 text

TSのボトムアップな勉強では到達でき ない世界があり、TSの外側の知識を使 うとそれが見えてくる

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

自分のTypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からないよ〜〜〜 2. TypeScript の恩恵を引き出す方法が分からないよ〜〜〜 3. 実用・運用に乗せる方法が分からないよ〜〜〜

Slide 31

Slide 31 text

なぜ TypeScript が必要なのか ● JavaScript でよくね? ● テストでよくね? ● Lintでよくね? ● assertionでよくね?

Slide 32

Slide 32 text

Twitterに書いたら 怒られました

Slide 33

Slide 33 text

ランタイムエラーを踏みまくれば 必要性が理解できる

Slide 34

Slide 34 text

ランタイムエラーへのassertionが めんどくさくなると、 必要性が理解できる

Slide 35

Slide 35 text

愚者は経験に学び、 賢者は歴史に学ぶ

Slide 36

Slide 36 text

プログラムを検証する学問の全体を知る ● 形式手法 ● 軽量形式手法の一つとして型システム ● 型: 値の分類 ● プログラムを実行することなく、プログラムがある種の振る舞いを起こさな いことを保証する

Slide 37

Slide 37 text

色々な検証方法がある中で、 型検査に焦点を当てる

Slide 38

Slide 38 text

MinCaml の存在を教わる ● 東京大学での CPU 実験で使わ れる教材の存在を教えてもらう ● プロセッサとコンパイラを実験 する課題の中で、OCaml で OCaml を実装する場面がある らしい ● 教材が一般公開されていて僕た ちも遊べる ● https://esumii.github.io/min- caml/

Slide 39

Slide 39 text

MinCaml で学べること プログラミング言語が動く仕組みを学べる 字句解析 構文解析 型検査 最適化 アセンブリの 出力

Slide 40

Slide 40 text

型検査 ● 教科書的には項や変数を定義し、型推論の規則を定義する。 ● 規則に従って、型環境を記録に使いながら、推論アルゴリズムを適用させて いく。 ● 型注釈がなくても与えられた状況から逆算して型を決定する。

Slide 41

Slide 41 text

MinCaml で型検査を作ってみて ● 型検査以外にも、そもそもプログラミング言語のソースコードがどうやって 実行されるのかが学べることが大きな財産 ● 型検査の正体がプログラムであることを知る。(魔法じゃなかった!) ● 型検査というプログラムによって、型システムが持つ機能を充実させられる という嗅覚を得る ● TypeScriptが如何に型破りであり、強力であり、柔軟であることを知る (MinCaml のやり方と全然違うことに後から気づき、MinCamlやらなくてよ かったことを学ぶ <- 逆説的かもしれないがめちゃくちゃ大事な経験)

Slide 42

Slide 42 text

挫折したら...

Slide 43

Slide 43 text

似たような教材は他にもあるので、 食いつまむと理解できるかもしれない

Slide 44

Slide 44 text

MinCaml 以外の選択肢 字句解析 構文解析 型検査 最適化 アセンブリの 出力 Go言語でつくるインタプリタ ● MinCaml の最初の壁の構文解析ま でがかなり丁寧 ● MinCamlではパーサージェネレー タを使うが、こちらは手書きする ● つまり、ナイーブで分かりやすい Goで学ぶはインタプリタ形式 なのでアセンブリは出力しな い。コンパイラ本もあるらし い

Slide 45

Slide 45 text

MinCaml 以外の選択肢 字句解析 構文解析 型検査 最適化 アセンブリの 出力 TaPL ● 項や規則の定義をして、それを実 際に実装する課題があり、理論と 実装の橋渡しが見えてくる ● 型システムにいろんな機能を増や していく進み方で学べる ● 挫折するが、輪読会などに行くと 学べる(tapl.ts)

Slide 46

Slide 46 text

MinCaml 以外の選択肢 字句解析 構文解析 型検査 最適化 アセンブリの 出力 ゼロから学ぶRust ● デバッガやシェルを実装させるどう考えても入門 書ではない入門書 ● RustでRustのサブセットを実装する章がある ● Rustはアフィン型やライフタイムという機能が あり、変数の消費を型で検査できる(1度使うと 使えなくなる) ● 型の世界でライフタイムを表現し、HM型推論を 実装する演習を通して、型検査に独自機能を足す と言うことが学べる

Slide 47

Slide 47 text

TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない a. TSなしでコードを書いてみてランタイムエラーをたくさん踏むと欲しくなる b. TSが保証しているようなことをテストなどで担保しようとすると、めんどくさくなって欲し くなる c. 形式手法など学問として存在している分野を学ぶと、トップダウンに理由を人に説明できる ようになる 2. TypeScript の恩恵を引き出す方法が分からない 3. 実用・運用に乗せる方法が分からない

Slide 48

Slide 48 text

TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない a. TSなしでコードを書いてみてランタイムエラーをたくさん踏むと欲しくなる b. TSが保証しているようなことをテストなどで担保しようとすると、めんどくさくなって欲し くなる c. 形式手法など学問として存在している分野を学ぶ 2. TypeScript の恩恵を引き出す方法が分からない 3. 実用・運用に乗せる方法が分からない

Slide 49

Slide 49 text

別言語のプラクティスを学ぶ ● F# ではこうする、OCamlではこうする ● 型と値、コンパイラがあたりまえにある言語はこう解釈される ● 型の制約を強める恩恵を知る

Slide 50

Slide 50 text

型と値の違いを意識する ● 型と値の違いを意識する ○ TSのtypeofとJSのtypeofを使うのが良い訓練 ● JSエコシステムにおけるコンパイルとは何かビルドとは何か ○ FlowやTSをビルドすると、型が消える ○ tsconfig の lib の中身を差し替えて、生成されるコードを見比べる ○ @babel/plugin-transform-typescript を読む

Slide 51

Slide 51 text

babel/plugin-transform-typescript https://babeljs.io/docs/babel-plugin-transform-typescript

Slide 52

Slide 52 text

型の上下関係を知り、any と向き合う ● TS使い始め: any 使って型推論を通すぜうぇーい ● 実行時エラー: もしかして any って悪いのか? ● Twitterでは: any 撲滅! ● 学び: any ってダメなのかも ● 冷静になって: そもそも any ってなんですか? 後に引き継いだ同僚が600箇所の エラーを直すことになる。 (本当にごめんなさい)

Slide 53

Slide 53 text

型の上下関係 ● 型の関係は supertype, subtype という上下関係で表現できる ● 何でも受け入れる型: unknown ● 何でも受け入れない型: never ● (上下関係の外側で) 両方の性質を持つ: any unknown never

Slide 54

Slide 54 text

構造的部分型 ● 「狭い型」と「広い型」 ● 狭い(厳しい)・広い(緩い) を構造で判断 ● 緩い側に厳しい側は代入できる ● サブタイプはスーパータイプに 代入できる

Slide 55

Slide 55 text

変性 ● Animal と Human というクラスがある ● サブタイプはスーパータイプに代入できる ● Animal animal = new Human() はできる ● Animal[] animals = new Human[2] はでき るのか? ● P1 が P2 のサブタイプである ⇒ P1[] が P2[] のサブタイプである? ● Java でよく言われていた問題らしい is-a 動物 (という概念)

Slide 57

Slide 57 text

TypeScript の変性はどうなのか ● 配列は共変 ● Javaと同じ問題を踏み抜いている! ● animals である [🙀, 🙀, 🙀]を humans[😱, 😱, 😱]になるように破壊しても型検査が怒 らない ● 何が問題か -> 配列を代入しても参照がコ ピーされるだけ。animalsの要素を入れ替え ると、humansの要素も書き換わり、human 専用メソッドを呼び出そうとすると、ラン タイムエラー ● と言う理由で FlowType を薦められていた 過去がある https://qiita.com/na-o-ys/items/aa56d678cdf0de2bdd79

Slide 58

Slide 58 text

Opaque ● TypeScript では userId👦 と ramenId🍜 を区別できない ● 構造的型付けでは、string という同じ構造 ● flowtype にはそれらを区別できる opaque という機能がある ○ https://flow.org/en/docs/types/opaque-types/

Slide 59

Slide 59 text

構造が違う型を無理やり定義する ● type UserId = string & {__userId: never}; ● type RamenId = string & {__ramenId: never};

Slide 60

Slide 60 text

型の上下関係と代入についてのまとめ ● any は何でも代入できるし、何にでも代入される ● いい加減な代入でランタイムエラー ● 変性によっていい加減な代入ができてしまうこともある ● 構造的部分型に起因する型の分類の難しさは、Opaqueで守れる

Slide 61

Slide 61 text

型の制約を強めるには ● 別言語プラクティスとして制約は強いほど強いほど良いらしい ● どのようにしたら強められるかという意識を常に持とう ○ never ○ narrowing ○ 判別共用体

Slide 62

Slide 62 text

exhaustive check ● if や switch で分岐を全てやり切った後 は never になる ● else 節や default 節で never かどうか を検査するようにすれば、分岐漏れをコ ンパイル時に気づける https://typescript-jp.gitbook.io/deep-dive/t ype-system/discriminated-unions

Slide 63

Slide 63 text

判別共用体を作る APIアクセスした結果をコンポーネントに出す状況を考える アクセス中は、ローダー、成功したら結果、失敗したらメッセージを出 したい アクセス中はデータもエラーも値には出てこないことを表現

Slide 64

Slide 64 text

判別共用体を作る ローディング中だけど、 データも存在しているという解釈もできてしまう

Slide 65

Slide 65 text

判別共用体を作る 真偽値や存在チェックをすることで、型が絞り込まれいくような、 定義の方法 F#でよくされるプラクティスらしい

Slide 66

Slide 66 text

TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない 2. TypeScript の恩恵を引き出す方法が分からない a. 別言語のプラクティスや設計ミスを知る b. 自分が教えてもらったのは、Java、F#、OCaml 3. 実用・運用に乗せる方法が分からない

Slide 67

Slide 67 text

TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない 2. TypeScript の恩恵を引き出す方法が分からない 3. 実用・運用に乗せる方法が分からない

Slide 68

Slide 68 text

ビルドを通せない ● Error Cause を使いたい ● Top Level Await を使いたい ● JSON を import したい ● import するときの拡張子には何を選んだらいいか分からない

Slide 69

Slide 69 text

tsc --init

Slide 70

Slide 70 text

tsc --init 物足りない

Slide 71

Slide 71 text

ErrorCause 独自エラーで投げ直したいけど、元のエラーの情報も保持した い!

Slide 72

Slide 72 text

ErrorCause https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error/cause

Slide 73

Slide 73 text

ErrorCause https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Error/cause 便利機能を使おうとすると ビルドエラー

Slide 74

Slide 74 text

オプションを使いこなす ● target: どのバージョンのJSに落とし込むか ● lib: targetがサポートしていない機能を実装するためのポリフィルを実装に 埋め込んでくれる(Promise, Array.prototype.hoge, … ● module: cjs, esm などのモジュール形式。TLA は ESM じゃないと動かない など、cjs だと同期的という制約があったりしてこのオプションをいじらな いとビルドできないものがある ● esModuleIntertop: 使うライブラリや既存コードによっては cjs との互換性 を意識しないとビルドできなくなる ● moduleResolution: ビルドツールが前提とする方法によって切り替える必要 が出てくる

Slide 75

Slide 75 text

ECMAScript それ自体を知る ● ビルドに関するエラーの8割はモジュールに対しる不理解によるもの(当人 比) ● モジュールとは何かを人に説明できるようになると良さそう ● IMO: 訓練として Jest と Vitest の比較などやってみると良さそう ● (ちなみに僕は自身ないです)

Slide 76

Slide 76 text

TypeScript 学習の壁 1. なぜ TypeScript が必要なのかが分からない 2. TypeScript の恩恵を引き出す方法が分からない 3. 実用・運用に乗せる方法が分からない a. ビルドできない理由の6割はモジュールに対する理解だと思うので、ECMAScript そのもの を勉強する b. ECMAScript 仕様輪読会 などの勉強会に参加すると良いと思う。 優しい人が教えてくれるはず🟢

Slide 77

Slide 77 text

TSを使うなら、これで十分!?

Slide 78

Slide 78 text

複雑な型パズルを解けるようになりそう なエッセンスはどこにもないが?

Slide 79

Slide 79 text

持論 型パズルなんて解く必要がない。アプリケーション開発にお いて、呼び出し側は Specific なので汎用性を意識した推論 をさせる必要が生まれない。最悪 as でも any でも使っとけ

Slide 80

Slide 80 text

持論 型パズルなんて解く必要がない。アプリケーション開発にお いて、呼び出し側は Specific なので汎用性を意識した推論 をさせる必要が生まれない。最悪 as でも any でも使っとけ 切り抜くなよ!

Slide 81

Slide 81 text

アプリケーションをライブラリを 作るように作る場合は必要😢

Slide 82

Slide 82 text

アプリケーションをライブラ リのように作ると言う表現、 uhyoさんが昔いってた気がす るんだけど見つけられず

Slide 83

Slide 83 text

アプリケーションをライブラリを 作るように作らないといけない状況 ● チーム全体、もしくはチームの垣根を超えて生産性に責任を持つ場合 ● レイヤードな設計をちゃんとしたい場合 ● インターフェースにこだわると自然にそうなっていってしまうかも

Slide 84

Slide 84 text

もしかして、 型パズルを解けると出世できる!?

Slide 85

Slide 85 text

もしかして、 型パズルを解けると出世できる!? 俺も出世するぞ!!!

Slide 86

Slide 86 text

型パズル力を鍛えるためには ● 巷のライブラリを読む ● ひたすら type-challenges を解く ● そういうのが得意な人にペアプロしてもらう

Slide 87

Slide 87 text

初級すら解けないよ〜😢

Slide 88

Slide 88 text

勝ちパターンを覚えよう&見つけよう

Slide 89

Slide 89 text

気づいたらライブラリを 作れるようになる

Slide 90

Slide 90 text

ライブラリに潜むぎょっとする機能 ● ジェネリクス ● extends ○ 型パラメータの extends ○ ? の前の extends ● keyof ● ? ● infer ● in ギョッ

Slide 91

Slide 91 text

勝ちパターン ● 当てはまる型を逆算する→ジェネリクス, infer ● 型の制約→extends ● 型の分岐→extends, ?(Conditional Type) ● 繰り返し→in(Mapped Types), 再帰

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

No content

Slide 94

Slide 94 text

MyPick<{hoge: number; fuga: string; piyo: number}, “hoge” | “fuga””> の結果を、{hoge: number; fuga: string } にしたい。 MyPick で呼ぶとして、UnionTypeになるB は オブジェクトA のキーで構成されないといけない 制約の extends, キーを抽出する keyof を使う

Slide 95

Slide 95 text

MyPick<{hoge: number; fuga: string; piyo: number}, “hoge” | “fuga””> の結果を、{hoge: number; fuga: string } にしたい。 MyPick で呼ぶとして、A からキーBを構成する要素で、 オブジェクトを抽出する操作を繰り返したい 繰り返しの in を使う

Slide 96

Slide 96 text

MyPick<{hoge: number; fuga: string; piyo: number}, “hoge” | “fuga””> の結果を、{hoge: number; fuga: string } にしたい。 MyPick で呼ぶとして、in で B から hoge と fuga が抽出されて繰り返されるので、A から その key に該当する要素を繰り返しで抽出されるように [key in K]: T[key] とする

Slide 97

Slide 97 text

No content

Slide 98

Slide 98 text

No content

Slide 99

Slide 99 text

Firstの結果を、T[0] にしたい。 T は配列であることを保証したい 制約の extends を使う、要素は何でも良いので any[]

Slide 100

Slide 100 text

配列であることが保証されるのであれば、空配列でなければ 0 番目には必ずアクセスできる 空配列かどうかを判断したい 分岐の extends ?、ありえないことを表す never を使う

Slide 101

Slide 101 text

注: Promise の入れ子 もサポートする

Slide 102

Slide 102 text

https://github.com/type-challenges/type-challenges/issues/24969

Slide 103

Slide 103 text

https://github.com/type-challenges/type-challenges/issues/24969 Promise から U を抽出したい Promise> から U を抽出したい T は Promise であるべきなので、extends PromiseLike Promise の入れ子を表現できていないが、入れ子の段階で繰り返しが必要であることと、 Collection(配列やオブジェクト)が対象でないことから Mapped Types を使えなさそうで、 再帰の可能性を視野に入れる。繰り返されることを考えると1重のPromiseで済みそうと予想

Slide 104

Slide 104 text

https://github.com/type-challenges/type-challenges/issues/24969 Promise から U を抽出したい マッチした型を抽出するので infer の出番

Slide 105

Slide 105 text

https://github.com/type-challenges/type-challenges/issues/24969 U が Promise なら二重のPromiseなので、もう一度 infer を適用したい。 再帰で MyAwaited を呼び出すか判定したいので PromiseLike かどうかを調べる 分岐の extends

Slide 106

Slide 106 text

https://github.com/type-challenges/type-challenges/issues/24969 これ以上 Promise で包まれていない時に再帰は停止する

Slide 107

Slide 107 text

その他よく使うパターン ● [number] ● [U, ...T] ● union distribution

Slide 108

Slide 108 text

実務で出番ある?

Slide 109

Slide 109 text

アプリケーションをライブラリを 作るように作らないといけない状況 ● チーム全体、もしくはチームの垣根を超えて生産性に責任を持つ場合 ● レイヤードな設計を徹底する場合

Slide 110

Slide 110 text

● ビジネスの都合上、あるフォーマットや構造に従うデータを扱わないといけ ない ● その構造の変換を扱う処理をするのならば、ビジネス知識を反映した便利な 関数と型を作らないといけない ● フォーマットの構造に合わせて、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)

Slide 111

Slide 111 text

汎用的な何かを作りたいなら 分岐と繰り返しは必須 ● 全てのパターンを分岐で網羅し尽くす: conditional types ● 規則を見つけて、繰り返しで適用する: mapped types, 再帰

Slide 112

Slide 112 text

汎用的な何かを作りたいなら 分岐と繰り返しは必須 ● 全てのパターンを分岐で網羅し尽くす: conditional types ● 規則を見つけて、繰り返しで適用する: mapped types, 再帰 チューリング完全

Slide 113

Slide 113 text

https://github.com/type-challenges/type-challenges/blob/main/README.ja.md

Slide 114

Slide 114 text

No content

Slide 115

Slide 115 text

汎用的な何かを作りたいなら 分岐と繰り返しは必須 ● 全てのパターンを分岐で網羅し尽くす: conditional types ● 規則を見つけて、繰り返しで適用する: mapped types, 再帰 というか型の世界に書い ていたのはもはや普通の プログラム!

Slide 116

Slide 116 text

余談: 感動したパターン

Slide 117

Slide 117 text

自分でトップダウンな知識を 手に入れに行く

Slide 118

Slide 118 text

強く静的に型付けられた 関数型言語から学ぶ ● 「強く静的に型づけられた関数型言語をやってみると新しい視点が手に入る よ」 ● OCaml, Rust, Haskell, Scala を勉強する ○ けど、難しすぎて独学はできないのでこれも手取り足取り教わった... 今思えば、TSにおける上達のコツのほとんどは、これらの言語を使って いると当たり前に身についていたものな気がしている

Slide 119

Slide 119 text

別言語でのプラクティスを知っているだ けで、良いTSのコードが書ける

Slide 120

Slide 120 text

当然、エコシステムも黙っちゃあいない

Slide 121

Slide 121 text

強く静的に型付けられた言語にある概念 を持ち込んでいるライブラリの例 ● 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 がしていることを実現する

Slide 122

Slide 122 text

Result 型の流行 ● try catch をし忘れる, エラーハンドリ ングのし忘れを型検査で防ぎたい ● 成功失敗を表現するオブジェクトで包 めば良いが、呼び出す側が毎回 Result を解かないといけないのがめんどくさ い ● Result という文脈を保ったまま計算す る方法を考える めんどくさい

Slide 123

Slide 123 text

文脈とは何か ● 失敗するかもしれない: Result ● 空かもしれない: Optional ● 結果が複数かもしれない: List

Slide 124

Slide 124 text

文脈は型を引数に取る ● Result, Option, List は bind(>>=) や map といった共通機能を持ち、文脈 を他の文脈と組み合わせるためのインターフェースとなる ● m a … 文脈m に包まれた a ● (>>=) :: m a -> (a -> m b) -> m b (※mは文脈) bind 演算子と呼ぶことを知らなくて、ググれ なくて困った思い出

Slide 125

Slide 125 text

型注釈から意味を読み取る ● m: 文脈(Resultなど ● m a -> (a -> m b) -> m b 👀

Slide 126

Slide 126 text

型注釈から意味を読み取る ● m a -> (a -> m b) -> m b 👀 👀 👀 じ〜〜〜〜

Slide 127

Slide 127 text

型注釈から意味を読み取る ● m a -> (a -> m b) -> m b ● 文脈に包まれた a を、a を引数にとって文脈に包まれた b を返すに渡すと、 文脈に包まれた b を返す ● 文脈の中身が a から b に入れ替わっている ● 文脈を保ったままの計算ができる ● 文脈を一回解いて、関数を適用して、文脈で包みなしてくれる ● どこかで見覚えが... -> flatMap ● [1, 2, 3].flatMap(el => [el]) 👉 [1, 2, 3]

Slide 128

Slide 128 text

意味を読み取れると不適切な使われ方に も気づける ● 失敗を表現する Result は、フォームの入力 エラー管理に使えそう? ● m a -> (a -> m b) -> m b ● Result -> (Input1 -> Result ) ● Input1 のエラー内容を忘れてしまっている ● 入力が複数のものに Result は適さない ○ Validated という構造で解決できる(Scala) https://blog.ojisan.io/monad-applicative/

Slide 129

Slide 129 text

静的に型付けられた関数型言語 から得た学び ● 型で文脈を表現するという手法 ● 型注釈を見つめると、何を抽象化したものなのかが見えてくる

Slide 130

Slide 130 text

正直、初見だとハードルが高い

Slide 131

Slide 131 text

結局これも全部、詳しい人に 手取り足取り教えてもらっていた...

Slide 132

Slide 132 text

手取り足取り教わってみて ● これを最初に押さえておくと上達が早まるチート知識が存在する ● プログラミング言語の仕組みそのものと、強く静的に型づけられた関数型プ ログラミング言語から学べることが多い。(OCamlでOCaml作る講義がある大学裏山・・・) ● TS特有の知識は、ライブラリを作るようにアプリケーションを作ろうとする と、学ばないといけない知識が炙り出される ● type-challenges がトレーニングとして良く、勝ちパターンを知ると急激に 上達し、その状態でライブラリを読むと答え合わせになる ● チート知識だけでも誰かから装着してもらえると効率が良い

Slide 133

Slide 133 text

手取り足取り教わるためには ● 僕は運が良くおせっかいな人たちに手取り足取り教えてもらえた ● が、運に恵まれるための努力はしていた。毎日コード書いて、自分でも情報 発信して、エンジニアの飲み会にはほぼ出かけて、焼肉を献上していた。 ● 最近、エンジニア教育に関するツイートが各所で盛り上がっており、手取り 足取り教わろうとする姿勢を嫌う意見をよく目にする。 ● でも、僕は嫌いじゃないので、僕でよければ是非お声がけください。僕も誰 かの力になりたいです。(焼肉は不要です)