Skip to content

Instantly share code, notes, and snippets.

@tail-call
Created June 19, 2023 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tail-call/6e2c0b3c9dd4ebfdc1b36347fa78dba6 to your computer and use it in GitHub Desktop.
Save tail-call/6e2c0b3c9dd4ebfdc1b36347fa78dba6 to your computer and use it in GitHub Desktop.
local TypeCase = require 'TypeCase'.TypeCase
local SomeClass = require 'SomeClass'.SomeClass
local function isPositve(x)
return type(x) == 'number' and x > 0
end
local result = TypeCase(2) {
'string', function ()
return 'string two'
end,
isPositive, function ()
return 'positive number two'
end,
'number', function ()
return 'number two'
end,
SomeClass, function ()
return 'class two'
end,
'nil', function ()
return 'nil two'
end,
nil, function ()
return 'something else two'
end,
}
print(result) -- prints 'positive number two'
--- Control flow functions
local function TypeCase(obj, fallthroughHandler)
return function (args)
for i = 1, #args, 2 do
local signature, action = args[i], args[i + 1]
local function doAction(o)
if type(action) == 'function' then
return action(o)
else
return action
end
end
if signature == nil then
return doAction(obj)
elseif type(signature) == 'string' then
if type(obj) == signature then
return doAction(obj)
end
elseif type(signature) == 'table' then
local mt = getmetatable(obj)
if mt and mt.__index == obj then
return doAction(obj)
end
elseif type(signature) == 'function' then
if signature(obj) then
return doAction(obj)
end
else
error('invalid TypeCase signature: ' .. tostring(signature))
end
end
if fallthroughHandler then
fallthroughHandler(obj)
end
end
end
local function ETypeCase (obj)
return TypeCase(obj, function ()
error('An object fell through ETypeCase expression: ' .. tostring(obj))
end)
end
return {
TypeCase = TypeCase,
ETypeCase = ETypeCase,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment