Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Pythonで鉄道指向プログラミング
Search
USABARASHI
July 20, 2022
Programming
1.6k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Pythonで鉄道指向プログラミング
USABARASHI
July 20, 2022
More Decks by USABARASHI
See All by USABARASHI
Nix入門 devShell
usabarashi
2
710
Other Decks in Programming
See All in Programming
AI 輔助遺留系統現代化的經驗分享
jame2408
1
1.1k
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
220
はてなアカウント基盤 State of the Union
cockscomb
1
1.2k
TypeScript+Orvalで実現する型安全かつ堅牢でスケーラブルなマルチチャネル通知基盤 / TSKaigi Night talks ~after conference~
d0riven
0
380
Snowflake Summitでの新機能 CoCo / CoWork / snowflake-summit-2026-overall-what-new-coco
tatsuhiro
1
210
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
620
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
180
ローカルLLMでどこまでコードが書けるか -縮小版 / How much code can be written on a local LLM Shortened
kishida
2
160
エンジニア向け会社紹介/Findy Company Profile
findyinc
6
360k
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
220
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
150
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
230
Featured
See All Featured
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Crafting Experiences
bethany
1
200
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
28
3.5k
エンジニアに許された特別な時間の終わり
watany
107
250k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
PRO
201
75k
How to Ace a Technical Interview
jacobian
281
24k
Faster Mobile Websites
deanohume
310
32k
The untapped power of vector embeddings
frankvandijk
2
1.8k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
RailsConf 2023
tenderlove
30
1.5k
Fantastic passwords and where to find them - at NoRuKo
philnash
52
3.8k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Transcript
Pythonで 鉄道指向プログラミング Haskell, Scala, F#, Rust, … etc のアレ Python
3.10, Pylance v2022.6.30 2022/07/20 @usabarashi 1
どんな人?こんな人 Python歴 • 〜2019/09: Elm, Scala, TSを書いていた • 2019/10: Pythonを触り始める
• 2022/06: 未だに「Pythonicって何やねん...」という日々 2
鉄道指向 プログラミング 3
失敗/成功の判断を掛け合わせる • Railway Oriented Programing • Domain Modeling Made Functional
- Chaining Result-Generating Functional • レールに乗らない失敗 /成功はType Errorになる • 失敗したら成功のレールには戻らな い • いつ失敗しても失敗のレールに乗る • 最後まで成功すると成功になる • 失敗の種類が決まっている 4
Haskell: do notation 5
Scala: For Comprehension 6
F#: Computation Expression 7
Rust: Question mark operator 8
Pythonで再現してみる 9
Python仕様 • from typing import Callable, Generic, TypeAlias, TypeVar ◦
T = TypeVar(“T”) ◦ class List(Generic[T]): ▪ Tは型が束縛される変数なので型変数 ▪ List[T]はT型を処理するList型 ▪ List[int]はint型を処理するList型 ▪ Callable[[A, B], C]はA型, B型を引数にとりC型を返却する関数 • from collections.abc import Generator ◦ variable = yield process() ◦ StopIteration.value ▪ Generator[Y, S, R] <: Iterator <: Iterable ▪ Y: yieldの右側のprocessの結果の型変数 ▪ S: = yieldの左側のvariableに束縛する値の型変数 ▪ R: StopIteration.valueの型変数 10
失敗/成功の型を定義する 失敗/成功の定義 class Either(Generic[L, R]): Either[L, R] 失敗の定義 class Left(Either[L,
R): Left[L, R] 成功の定義 class Right(Either[L, R]): Right[L, R] 11
失敗/成功の型を定義する 失敗/成功のどちらかを返す def either(...) -> Either[L, R]: if …: return
Left[L, R](...) else: return Right[L, R](...) 12
シグネチャに失敗の値の型を定義する 失敗したらLeft[str, Any]を返す return Left[str, Any] 成功したらRight[str, Any]を返す return Right[str,
Any] ※ TypeAliasから型変数を指定できる EitherDo: TypeAlias = Generator[Either[L, Any], None, R] 13
EitherDo: TypeAlias = Generator[Either[L, Any], None, R] 上から下へ, 右から左への二次元と考える と理解しやすい
↓ =yield from Left[L, Any] ↓ Any=yield from Right[L, Any] return R StopIteration.value 一連の処理をGenerator関数で定義する 14
失敗を早期リターンする ↓ =yield from Left[L, Any] サブジェネレーターからLeft[L, Any]を貰う class Either(Generic[L,
R]): @abstractmethod def __iter__(self) -> Generator[Either[L, R], None, R]: 失敗ならLeft[L, Any]をそのままリターンする @staticmethod def do(...) -> Callable[P, Either[L, R]] … except ShortCircuit as short_circuit: return cast(Monad[A], short_circuit.state) …. ※ 失敗パターンはシグネチャに明記され ている 15
途中の処理結果を束縛する ↓ Any=yield from Right[L, Any] サブジェネレーターからRight[L, Any]を貰う class Either(Generic[L,
R]): @abstractmethod def __iter__(self) -> Generator[Either[L, R], None, R]: 成功ならサブジェネレーターのRをsendする @staticmethod def do(...) -> Callable[P, Either[L, R]] … case _ if type(yield_) is type(composite): composite = composite.flat_map(lambda _: cast(Monad[Any], yield_)) ※ サブジェネレーターの R: StopIteration.valueで暗黙的に束縛される 16
成功をリターンする return R StopIteration.value yieldがなくなったらreturnに相当する StopIteration.valueをリターンする @staticmethod def do(...) ->
Callable[P, Either[L, R]] … return cast(Monad[A], composite.map(lambda _: result)) ※ 成功のRight[L, R]型へあわせる 17
失敗/成功のどちらかだけ である可能性を定義する SubType: TypeAlias = Left[L, R] | Right[L, R]
@property def pattern(self) -> SubType[L, R]: return self ※ どこから継承されるか分からないので 可能性を具体的に制限する ※ 動的なメソッドだとtype narrowingが固 定されないのでpropertyで静的な値として 定義する pattern() pattern 18
失敗/成功を判定する class Left(Either[L, R]): __match_args__ = ("value",) self.value class Right(Either[L,
R]): __match_args__ = ("value",) self.value ※ パターンを網羅できていない場合は警 告が表示される 19
同じ構文で記述する: nullかも知れない • if var is None: • if var
is not None: • if isinstance(var, None): とか書かない ※ if Xxxx is type(var)は type narrowingされない 20
同じ構文で記述する: 例外が発生するかも知れない try: … except ExceptionA as exception_a: … raise
ExceptionB from exception_a except Exception: … raise else: … とか書かない ※ どこからどのようなExceptionがraiseされているか 静的解析できない 例外とは何か例外的なもの(ある意味、あきらめ)を表現するものであるとした場合、失敗は想定できる結 果であるため、その失敗を例外としてモデリングすることは意味的におかしいことになってしまいます。 セキュア・バイ・デザイン - 安全性を考えた処理失敗時の対策 21
文でなく式にする 文: 処理 式: 結果 = 処理 def method(self: A,
function: Callable[[A], B]) -> B: … result = sample_a .method(lambda self: SampleB(self.value)) def fold( self, left: Callable[[L], U], right: Callable[[R], U] ) -> U: … json_result = either.fold( left=lambda error: Json変換処理(error), right=lambda result: Json変換処理(result) ) 22
で, 実務で使えるの? 23
ビジネスロジック型パズル 24
ビジネスロジック型パズル 25
ビジネスロジック型パズル 26
ビジネスロジック型パズル 27
エンタープライズの鉄道 • 申請 ◦ 決裁 ◦ 未承認, 却下 • 機密
◦ 参照権限あり ◦ 参照権限なし 28
参考文献 • PyPI: pycategory • Railway Oriented Programing • Domain
Modeling Made Functional • 明日から使える実践エラーハンドリング • セキュア・バイ・デザイン • 圏論とモナドシリーズ • Scala, Scalaz, Cats 29