Created
May 31, 2019 17:51
-
-
Save Nymphium/3f13568f93ce36a37e76ef873dfd19b7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type id = int | |
type scene = { | |
id: id; | |
content: unit -> unit | |
} | |
effect Resume : scene -> unit | |
effect Switch : unit | |
let control th = | |
let h th = | |
match th () with | |
| _ -> fun () -> () | |
| effect Switch k -> | |
fun () -> ignore @@ continue k () | |
in | |
let scenes : (id, unit -> unit) Hashtbl.t = Hashtbl.create 10 in | |
match th () with | |
| x -> x | |
| effect (Resume {id; content}) k -> | |
let () = | |
match Hashtbl.(find_opt scenes id) with | |
| None -> | |
let rest = h content in | |
Hashtbl.(add scenes id rest) | |
| Some cache -> | |
let rest = h cache in | |
Hashtbl.(replace scenes id rest) | |
in | |
continue k () | |
let scene1 () = | |
print_endline "Hello"; | |
perform Switch; | |
print_endline "bye" | |
let scene2 () = | |
print_endline "spawn" | |
let shash content = | |
let id = Random.int 1000000 in | |
{id; content} | |
let resume c = perform (Resume (shash c)) | |
let main () = | |
control @@ fun () -> | |
resume scene1; | |
resume scene2; | |
resume scene1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local eff = require('eff') | |
local inst, perform, handlers = eff.inst, eff.perform, eff.handlers | |
local Switch = inst() | |
local Resume = inst() | |
local Log = inst() | |
local scene1 = function() | |
perform(Log("hello")) | |
perform(Switch()) | |
print("bye") | |
end | |
local scene2 = function() | |
print("spawn") | |
end | |
local h = handlers{ | |
function(x) return x end, | |
[Switch] = function(k) | |
return k | |
end | |
} | |
local control = function(f) | |
local scenes = {} | |
return handlers{ | |
function(x) return x end, | |
[Resume] = function(k, scene) | |
local cache = scenes[scene] | |
if not cache then | |
local rest = h(scene) | |
scenes[scene] = rest | |
else | |
local rest = cache() | |
scenes[scene] = rest | |
end | |
return k() | |
end | |
}(f) | |
end | |
local log_collector = handlers { | |
function(x) return x end, | |
[Log] = function(k, msg) | |
io.stderr:write("\27[31;1;4m" .. msg .. "\27[0m\n") | |
return k() | |
end | |
} | |
log_collector(function() | |
control(function() | |
local resume = function(x) return perform(Resume(x)) end | |
resume(scene1) | |
resume(scene2) | |
resume(scene1) | |
end) | |
end) | |
local scene1 = coroutine.create(function() | |
print("hello") | |
coroutine.yield() | |
print("world") | |
end) | |
local scene2 = coroutine.create(function() | |
print("spawn") | |
end) | |
do | |
coroutine.resume(scene1) | |
coroutine.resume(scene2) | |
coroutine.resume(scene1) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment