Created
June 19, 2023 14:55
-
-
Save tail-call/6e2c0b3c9dd4ebfdc1b36347fa78dba6 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
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' |
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
--- 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