ONE-SHOT Algebraic Effects for Lua!
$ luarocks --local install eff
eff
provides four objects, inst
, perform
and handler
.
inst
generates an effect instance.
perform
invoke the passed effect.
local Write = inst() -- instantiation
perform(Write("Hello!")) -- invocation
handler(h)
handler
requires a table and returns a handling function.
The table has fields, a value handler as val
and [Eff]
as an effect handler corresponding to Eff
.
"Handling an expression with a handler" is translated into an application passing a thunk, containing the expression, to the handling function.
local printh = handler {
val = function(v) print("printh ended", v) end,
[Write] = function(k, arg)
print(arg)
k()
end,
[Read] = function(k)
return k("baa")
end
}
printh(function()
local x = perform(Write("hello"))
return x
end)
--[[ prints:
hello
printh ended nil
]]
The continuation effect handler
received is ONE-SHOT, in other words, the continuatoin cannot run more than twice.
handler({
val = function(v) print("printh ended", v) end,
[Write] = function(k, arg)
print(arg)
k()
k() -- call continuation twice
end
})(function()
perform(Write("Foo"))
end)
--[[prints
lua: ./eff.lua:91: ./eff.lua:82: continuation cannot be performed twice
stack traceback:
[C]: in function 'error'
./eff.lua:91: in local 'printh'
../example/example.lua:28: in main chunk
[C]: in ?
]]
MIT