![Page 1: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/1.jpg)
0から知った気になるAlgebraic Effects
2019/09/30びしょ〜じょ
![Page 2: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/2.jpg)
本日の内容
Algebraic Effectsを
知った気にさせる
![Page 3: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/3.jpg)
自己紹介
● 筑波大学大学院M2
Algebraic Effectsからコルーチンに変換する研究
● 株式会社HERPでエンジニア
TSとかたまにHaskellを書いてる
こんにちは、びしょ~じょです
We're hiring!
![Page 4: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/4.jpg)
まずはじめに
皆さんはAlgebraic Effects知ってますか? 🙋
● 知ってるし書いたことがある
● 名前は聞いた
● 知らない
![Page 5: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/5.jpg)
Algebraic Effectsを一言でいうと
限定継続が取得できる
例外およびハンドラ
![Page 6: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/6.jpg)
限定継続🤔❓
![Page 7: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/7.jpg)
継続
継続は分かりますか?🙋
● わたしはschemerです
● はいはいコールバック関数ね
● 知らない
![Page 8: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/8.jpg)
コールバック関数です!!!!! (完)
継続
![Page 9: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/9.jpg)
例: ファイルを読み込み、結果をコールバック関数に渡す
readFile(file, res ⇒ { ...... })
継続
![Page 10: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/10.jpg)
例: ファイルを読み込み、結果をコールバック関数に渡す
これ継続
readFile(file, res ⇒ { ...... })
継続
![Page 11: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/11.jpg)
readFile(file, res ⇒ { ...... })
継続
![Page 12: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/12.jpg)
const res = await promisify(readFile)(file);......
readFile(file, res ⇒ { ...... })
継続
![Page 13: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/13.jpg)
const res = await promisify(readFile)(file);......
readFile(file, res ⇒ { ...... })
promisify(readFile)(file).then(res ⇒ {......});
継続
![Page 14: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/14.jpg)
const res = await promisify(readFile)(file);......
readFile(file, res ⇒ { ...... })
promisify(readFile)(file).then(res ⇒ {......});
継続
![Page 15: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/15.jpg)
前の計算結果を使って実行する残りの計算
const t = f(10);const u = g(t);const v = h("aaa");......
継続
![Page 16: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/16.jpg)
前の計算結果を使って実行する残りの計算 x ▷ k ≡ k(x)
f(10)▷ ((t) ⇒ g(t)▷ ((u) ⇒ h("aaa")▷ ((v) ⇒ ......)))
const t = f(10);const u = g(t);const v = h("aaa");......
継続渡しスタイル
継続
![Page 17: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/17.jpg)
前の計算結果を使って実行する残りの計算 x ▷ k ≡ k(x)
f(10)▷ ((t) ⇒ g(t)▷ ((u) ⇒ h("aaa")▷ ((v) ⇒ ......)))
const t = f(10);const u = g(t);const v = h("aaa");......
継続渡しスタイル
継続
![Page 18: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/18.jpg)
前の計算結果を使って実行する残りの計算 x ▷ k ≡ k(x)
f(10)▷ ((t) ⇒ g(t)▷ ((u) ⇒ h("aaa")▷ ((v) ⇒ ......)))
const t = f(10);const u = g(t);const v = h("aaa");......
継続渡しスタイル
継続
![Page 19: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/19.jpg)
前の計算結果を使って実行する残りの計算 x ▷ k ≡ k(x)
f(10)▷ ((t) ⇒ g(t)▷ ((u) ⇒ h("aaa")▷ ((v) ⇒ ......)))
const t = f(10);const u = g(t);const v = h("aaa");......
継続渡しスタイル
継続
![Page 20: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/20.jpg)
継続が使えると…
コントロールを扱う機能がユーザレベルで実装できる
● バックトラック
● マルチスレッド
などなど
継続
![Page 22: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/22.jpg)
⚠ しばらくRacketで行きます
呼ばれた位置からの継続を関数としてfnに渡す
継続が呼ばれたあとはcall/ccには戻ってこない
(call/cc fn)
継続 - call/cc (call with current-continuation)
![Page 23: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/23.jpg)
(let [(x (call/cc (λ (k) (+ 2 (k 4)))))] x)
継続 - call/cc (call with current-continuation)
![Page 24: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/24.jpg)
☑呼ばれた位置からの継続を関数として渡す
(let [(x (call/cc (λ (k) (+ 2 (k 4)))))] x)
継続 - call/cc (call with current-continuation)
![Page 25: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/25.jpg)
☑呼ばれた位置からの継続を関数として渡す
☑継続が呼ばれたあとはcall/ccには戻ってこない
(let [(x (call/cc (λ (k) (+ 2 (k 4)))))] x)
⇒ (let [(x 4)] x)⇒ returns 4
継続 - call/cc (call with current-continuation)
![Page 26: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/26.jpg)
(define (div-fail xs fallback) (call/cc (λ (k) (map (λ (e) (if (= e 0) (k fallback) (/ e 2))) xs))))
呼ばれた位置からの継続を取得継続に
fallbackを渡して脱出
継続 - call/ccと大域脱出
![Page 27: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/27.jpg)
(let [(x (div-fail '(3 4 5 6) '(1)))] x)
継続 - call/ccと大域脱出
![Page 28: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/28.jpg)
(let [(x (div-fail '(3 4 5 6) '(1)))] x)
⇒ returns '(3/2 2 5/2 3)
継続 - call/ccと大域脱出
![Page 29: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/29.jpg)
(let [(y (div-fail '(1 2 0 3) '(1)))] y)
継続 - call/ccと大域脱出
![Page 30: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/30.jpg)
(let [(y (div-fail '(1 2 0 3) '(1)))] y)
div-failから見た継続
継続 - call/ccと大域脱出
![Page 31: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/31.jpg)
(let [(y (div-fail '(1 2 0 3) '(1)))] y)
⇒ (let [(y '(1))] y)⇒ returns '(1)
継続 - call/ccと大域脱出
![Page 32: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/32.jpg)
限定 継続
![Page 33: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/33.jpg)
限定 継続
- call/ccプログラムの残りすべてを継続として利用
![Page 34: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/34.jpg)
- call/ccプログラムの残りすべてを継続として利用
⇒ ちょっと使いづらい😅
限定 継続
![Page 35: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/35.jpg)
- call/ccプログラムの残りすべてを継続として利用
⇒ ちょっと使いづらい😅
- 限定継続プログラムの残りの特定の範囲
を継続として利用
⇒ 取り回しが良い🙆
限定 継続
![Page 36: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/36.jpg)
限定 継続 - shift/reset
![Page 37: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/37.jpg)
式eのスコープ内で継続kを利用する
(shift k e)
限定 継続 - shift/reset
![Page 38: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/38.jpg)
式eのスコープ内で継続kを利用する
継続の範囲をe内に限定する
(shift k e)
(reset e)new
限定 継続 - shift/reset
![Page 39: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/39.jpg)
その他の限定継続演算子: control/prompt, cupto, etc.
式eのスコープ内で継続kを利用する
継続の範囲をe内に限定する
(shift k e)
(reset e)
限定 継続 - shift/reset
new
![Page 40: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/40.jpg)
浅井健一, shift/resetプログラミング入門 を参考
(let [(f {reset (string-append (shift k (λ () (k "hello"))) " world")})] (f))
限定 継続 - shift/reset
![Page 41: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/41.jpg)
浅井健一, shift/resetプログラミング入門 を参考
(let [(f (reset (string-append (shift k (λ () (k "hello"))) " world")))] (f))
継続の範囲を限定
限定 継続 - shift/reset
![Page 42: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/42.jpg)
浅井健一, shift/resetプログラミング入門 を参考
(let [(f (reset (string-append (shift k (λ () (k "hello"))) " world")))] (f))⇒ (let [(f (λ () (string-append "hello" " world")))] (f))
shiftの結果が返る
限定 継続 - shift/reset
![Page 43: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/43.jpg)
浅井健一, shift/resetプログラミング入門 を参考
(let [(f (reset (string-append (shift k (λ () (k "hello"))) " world")))] (f))⇒ (let [(f (λ () (string-append "hello" " world")))] (f))⇒ returns "hello world"
限定 継続 - shift/reset
![Page 44: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/44.jpg)
限定継続が使えると…
● call/cc !!● 型付きprintf● Stateモナド
限定 継続
![Page 45: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/45.jpg)
限定継続が使えると…
● call/cc !!● 型付きprintf● Stateモナド
限定 継続
モナド全般
![Page 46: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/46.jpg)
例外+ハンドラ
![Page 47: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/47.jpg)
皆さん例外は分かりますか?🙋
● MonadError● もちろん知ってる
例外+ハンドラ - try-catch
![Page 48: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/48.jpg)
これは皆さんご存知try-catch (OCamlではtry-with)
try 3 + raise Not_found with| Not_found → print_endline "not found"
例外+ハンドラ - try-catch
![Page 49: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/49.jpg)
これは皆さんご存知try-catch (OCamlではtry-with)
● 例外が起きるとハンドラにジャンプする
● 例外発生位置からの残りの計算は破棄される
try 3 + raise Not_found with| Not_found → print_endline "not found"
例外+ハンドラ - try-catch
![Page 50: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/50.jpg)
Algebraic Effects
![Page 51: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/51.jpg)
Algebraic Effectsを一言でいうと(再)
限定継続が取得できる
例外およびハンドラ
![Page 52: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/52.jpg)
● 計算エフェクトを例外のthrowのように発生
● ハンドラにジャンプ
● ハンドラのスコープ内の継続を同時に取得して
エフェクト発生位置から復帰できる
正しくは Algebraic Effects and HandlersAlgebraic Effects(2003) + Effect Handlers(2012)略して "Algebraic Effects" または "Algebraic Effect Handlers"
Algebraic Effects = 限定継続 + 例外&ハンドラ
![Page 53: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/53.jpg)
effect Option : 'a option → 'a
handle let ox = lookup "key" map in let x = perform (Option ox) in Some (x + 5)with| effect (Option (Some v)) k → k v| effect (Option None) _k → None
Algebraic Effects - Option Monad
![Page 54: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/54.jpg)
effect Option : 'a option → 'a
handle let ox = lookup "key" map in let x = perform (Option ox) in Some (x + 5)with| effect (Option (Some v)) k → k v| effect (Option None) _k → None
エフェクトを定義
Algebraic Effects - Option Monad
![Page 55: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/55.jpg)
effect Option : 'a option → 'a
handle let ox = lookup "key" map in let x = perform (Option ox) in Some (x + 5)with| effect (Option (Some v)) k → k v| effect (Option None) _k → None
エフェクトを発生エフェクトを定義
Algebraic Effects - Option Monad
![Page 56: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/56.jpg)
effect Option : 'a option → 'a
handle let ox = lookup "key" map in let x = perform (Option ox) in Some (x + 5)with| effect (Option (Some v)) k → k v| effect (Option None) _k → None
エフェクトを発生エフェクトを定義
Someを剥がして継続に値を渡す
Algebraic Effects - Option Monad
![Page 57: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/57.jpg)
effect Option : 'a option → 'a
handle let ox = lookup "key" map in let x = perform (Option ox) in Some (x + 5)with| effect (Option (Some v)) k → k v| effect (Option None) _k → None
エフェクトを発生エフェクトを定義
継続を破棄(c.f.例外処理)
Algebraic Effects - Option Monad
![Page 58: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/58.jpg)
エフェクトはtry-catch同様に該当するハンドラで捕捉される
⇒ ハンドラのネストで複数のエフェクトをハンドル可能
👍エフェクトのハンドリングがcomposable におこなえる
Algebraic Effects - ハンドラのネストと合成性
![Page 59: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/59.jpg)
effect GetLine : () → string
let with_stdin th = handle th () with | effect (GetLine ()) k → k (get_line ())
let with_option th = ......
標準入力から読む
Algebraic Effects - ハンドラのネストと合成性
![Page 60: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/60.jpg)
let read_int () = let line = perform (GetLine ()) in perform (Option (int_of_string_opt line))
let int_of_string_opt : string → int option = ......
2種類のエフェクトを発生
Algebraic Effects - ハンドラのネストと合成性
![Page 61: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/61.jpg)
let plus_two_lines () = let a = read_int () in let b = read_int () in Some (a + b)
Algebraic Effects - ハンドラのネストと合成性
![Page 62: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/62.jpg)
let plus_two_lines () = let a = read_int () in let b = read_int () in Some (a + b)
let main () = with_option (fun () → with_stdin plus_two_lines)
Algebraic Effects - ハンドラのネストと合成性
![Page 63: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/63.jpg)
Algebraic Effectsで何ができる?
● Dependency Injection● async/await● 論理プログラミング
などなど
![Page 64: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/64.jpg)
Algebraic Effectsを使おう
● 言語(,処理系)○ Eff○ Koka○ Multicore OCaml○ Frank
などなど
● ライブラリ○ eff.lua for Lua (拙作)○ ruff for Ruby (拙作)○ effective-rust for Rust○ gauche-effects for Scheme
![Page 65: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/65.jpg)
様々な実装方法
● コールスタックを直接触るlibhandler
● 限定継続gauche-effects, effekt, 『Eff Directly in OCaml』
● コルーチンeff.lua, ruff, effective-rust, 弊研究
Algebraic Effectsを実装しよう
![Page 66: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/66.jpg)
まとめ
● Algebraic Effectsは限定継続の取れる例外
● Algebraic Effectsはなんか色々できて強い
● Algebraic Effectsは実はすぐに触れる
![Page 67: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/67.jpg)
まとめ
話してないこと:
● value handler● 型システム
● 『What is algebraic …… ?』
などなど
![Page 68: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/68.jpg)
まとめ
話してないこと:
● value handler● 型システム
● 『What is algebraic …… ?』
などなど
宿題です!!!
![Page 69: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/69.jpg)
参考文献
● Andrej Bauer and Matija Pretnar. Programming with algebraic effects and handlers. In: Journal of Logical and Algebraic Methods in Programming 84.1 (2015), pp. 108–12
● 浅井健一. shift/resetプログラミング入門. In: ACM SIG-PLAN Continuation Workshop 2011 (2011)
● びしょ~じょ. How do you implement algebraic effects?. In: effect system勉強会 (2019)● R. Kent Dybvig, Simon Peyton Jones, and Amr Sabry. A monadic framework for delimited
continuations. In: Journal of Functional Programming 17.6 (2007), pp. 687-730.● Andrej Bauer. What is algebraic about algebraic effects and handlers?. In: arXiv preprint
arXiv:1807.05923 (2018)● Oleg Kiselyov and KC Sivaramakrishnan. Eff directly in OCaml. In: ACM SIGPLAN Workshop
on ML 2016 Sep. (2016)
Q&A
![Page 70: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/70.jpg)
a.k.a. 副作用 誤解を与えかねないのでしばしば言い換えられる
やりたい計算(Num a ⇒ a)に対して本道でないもの(Maybe)
計算エフェクト
Num a ⇒ a ⇔ Num a ⇒ Maybe a
モナドを使うと計算エフェクトの操作を隠蔽できる
class Applicative m ⇒ Monad m where (≫=) :: m a → (a → m b) → m b return :: a → m a
![Page 71: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/71.jpg)
Extensible Effectsとの関連性
type-directedなAlgebraic Effectsの実装方法だと思う
⇔ 限定継続、コルーチンはexpression-directed
Extensible Effects 限定継続 コルーチン
強い型システム multi-prompt shit/reset
asymmetric coroutines
![Page 72: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/72.jpg)
無さそう、AEで実装できるがメリットが少ない
React Hooksとの関連性……🤔
React Hooks → Algebraic Effects
useHoge → Hogeエフェクトの発生
(React内部実装) → ハンドラ
次のレンダリング? → 継続
● Reactが隠蔽していた実装を自分でやる必要がある● 一般に、言語レベルで扱える継続はコストが高い● 継続を末尾位置で必ず呼ぶ(i.e. 複製、破棄などしない)ので旨
味がない
![Page 73: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/73.jpg)
- Dependency Injection
インタフェースに対して実装をあとから入れる
- Algebraic Effects
エフェクトのシグネチャ(インタフェース)に対して
ハンドラ(実装)をあとから入れる
Algebraic Effects - Dependency Injection🤯
![Page 74: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/74.jpg)
effect GetUsers : () → user list
let mock_get_users th = handle th () with | effect (GetUsers ()) k → k (List.create ~size:10 ~val:dummy_data)
let prod_get_users th = handle th () with | effect (GetUsers ()) k → k(DB.get_users ())
Algebraic Effects - Dependency Injection🤯
![Page 75: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/75.jpg)
effect GetUsers : () → user list
let mock_get_users th = handle th () with | effect (GetUsers ()) k → k (List.create ~size:10 ~val:dummy_data)
let prod_get_users th = handle th () with | effect (GetUsers ()) k → k(DB.get_users ())
Algebraic Effects - Dependency Injection🤯
ユーザを取得するエフェクトを定義
ダミーデータを渡す
実際のデータを渡す
![Page 76: 0から知った気になる Algebraic Effects · 0から知った気になる Algebraic Effects 2019/09/30 びしょ〜じょ](https://reader035.vdocuments.net/reader035/viewer/2022071215/6044e311a8403d70803fe93a/html5/thumbnails/76.jpg)
let app () =
let users = perform (GetUsers ()) in
......
let test_main () =
mock_get_users app
let prod_main () =
prod_get_users app
ハンドラの切り替えで実装を選べる
Algebraic Effects - Dependency Injection🤯