Last active
October 21, 2023 19:11
-
-
Save hishamhm/fa7952667c775392307ec31456426852 to your computer and use it in GitHub Desktop.
Type checked units using records in Teal
This file contains hidden or 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
| -- 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