Skip to content

Instantly share code, notes, and snippets.

@hishamhm
Last active October 21, 2023 19:11
Show Gist options
  • Select an option

  • Save hishamhm/fa7952667c775392307ec31456426852 to your computer and use it in GitHub Desktop.

Select an option

Save hishamhm/fa7952667c775392307ec31456426852 to your computer and use it in GitHub Desktop.
Type checked units using records in Teal
-- units.tl
------------------------------------------------------------------------------
local type Hour = record
n: number
metamethod __call: function(self: Hour, n: number): Hour
metamethod __add: function(d1: Hour, d2: Hour): Hour
metamethod __tostring: function(self: Hour): string
end
local Hour_mt: metatable<Hour>
Hour_mt = {
__call = function(_: Hour, n: number): Hour
return setmetatable({ n = n }, Hour_mt)
end,
__add = function(d1: Hour, d2: Hour): Hour
return Hour(d1.n + d2.n)
end,
__tostring = function(self: Hour): string
return tostring(self.n) .. " h"
end,
}
setmetatable(Hour, Hour_mt)
------------------------------------------------------------------------------
local type Kmh = record
n: number
metamethod __call: function(self: Kmh, n: number): Kmh
metamethod __tostring: function(self: Kmh): string
end
local Kmh_mt: metatable<Kmh>
Kmh_mt = {
__call = function(_: Kmh, n: number): Kmh
return setmetatable({ n = n }, Kmh_mt)
end,
__tostring = function(self: Kmh): string
return tostring(self.n) .. " km/h"
end,
}
setmetatable(Kmh, Kmh_mt)
------------------------------------------------------------------------------
local type Kilometer = record
n: number
metamethod __call: function(self: Kilometer, n: number): Kilometer
metamethod __div: function(km: Kilometer, h: Hour): Kmh
metamethod __div: function(km: Kilometer, n: number): Kilometer
metamethod __add: function(d1: Kilometer, d2: Kilometer): Kilometer
end
local Kilometer_mt: metatable<Kilometer>
Kilometer_mt = {
__call = function(_: Kilometer, n: number): Kilometer
return setmetatable({ n = n }, Kilometer_mt)
end,
__add = function(d1: Kilometer, d2: Kilometer): Kilometer
return Kilometer(d1.n + d2.n)
end,
__div = function(d1: Kilometer, d2: number | Kilometer): any
if d2 is number then
return Kilometer(d1.n / d2)
else
return Kmh(d1.n / d2.n)
end
end,
__tostring = function(self: Kilometer): string
return tostring(self.n) .. " km"
end,
}
setmetatable(Kilometer, Kilometer_mt)
------------------------------------------------------------------------------
local t1 = Hour(5)
local d1 = Kilometer(800)
print("distance...:", d1)
print("time.......:", t1)
print("speed......:", d1 / t1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment