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