Skip to content

Instantly share code, notes, and snippets.

@Nymphium
Created May 31, 2019 17:51
Show Gist options
  • Save Nymphium/3f13568f93ce36a37e76ef873dfd19b7 to your computer and use it in GitHub Desktop.
Save Nymphium/3f13568f93ce36a37e76ef873dfd19b7 to your computer and use it in GitHub Desktop.
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
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