Koka
メモ
例
code:koka
effect foo
ctl fooing(i: int) : bool
fun bar() : foo bool
fooing(1)
fun baz()
bar()
pub fun main()
println("hello")
with ctl fooing(i)
println("i is " ++ i.show)
resume(i==0)
baz()
println("world")
barは直接fooを使うのでシグネチャに明記する必要があるが、bazはfooを間接的に使うだけなので明記する必要はない(推移的に推論される)
全部手で書くのはさすがに面倒だよね
code:koka
effect sayer
ctl say(s: string) : ()
fun handle-say1(action)
with handler
fun say(s)
println(s)
action()
fun handle-say2(action)
with handle-say1
with handler
fun say(s)
say(s ++ "!")
action()
pub fun main()
with handle-say2
say("moo")
エフェクトを加工して再発生させる例
この例だとシグネチャ全く書かなくていいんだな
mapなどの関数はエフェクトに対して多相
シグネチャ: map : (xs : list<a>, f : (a) -> e b) -> e list<b>
fがエフェクトeを使うとき、それは結果にも引き継がれる
Moreover, these handlers can be composed freely so the interaction between, say, async-await and exceptions are well-defined.
エフェクトの定義には継続が出てこない。継続が出てくるのはハンドラのほう
実験言語はsyntax sugar入れるのはほどほどにしてほしい(感想)
Tail-Resumptive Operation: 継続を最後に一度だけ呼ぶやつ(一番多いパターン)
このときwith ctlではなくwith funが使える
単に短いだけでなく最適化に使われる
with handler return: どのctlも通らなかったときに使われる?
奇妙な感じだが、確かにこういうものがないと例外をmaybeに変換するみたいなのが書けない
3.4.6. Combining Handlers
algebraic effects and handlersを制御構造の下回りとすることについて
vs. shift/reset: 型付けがシンプルで済むらしい?
vs. call/cc: 継続の終点が限られてるので効率のよい実装ができるとか組み合わせやすいとか
vs. moand: 合成がしやすい
そのかわりに継続モナドのようなnon-algebraicなモナド(とは?)は表現できないらしい