feat: changes to formatting metamethods and examples

This commit is contained in:
Erica Marigold 2024-04-01 12:05:59 +05:30
parent 538fd90b0c
commit f380daf7b2
No known key found for this signature in database
GPG key ID: 2768CC0C23D245D1
3 changed files with 62 additions and 23 deletions

View file

@ -1,34 +1,41 @@
local Option = {} local Option = {}
export type Option<T> = typeof(Option) & { export type Option<T> = typeof(Option) & {
_optValue: T?, _optValue: T?,
typeId: "Option" typeId: "Option",
} }
function None<T>(): Option<T> function None<T>(): Option<T>
return Option.new(nil) :: Option<T> return Option.new(nil) :: Option<T>
end end
function Some<T>(val: T): Option<T> function Some<T>(val: T): Option<T>
return Option.new(val) :: Option<T> return Option.new(val) :: Option<T>
end end
function Option.new<T>(val: T?) function Option.new<T>(val: T?)
return setmetatable({ return setmetatable(
_optValue = val, {
typeId = "Option" _optValue = val,
} :: Option<T>, { typeId = "Option",
__index = Option, } :: Option<T>,
__tostring = function(self) {
-- Return formatted enum variants too __index = Option,
__tostring = function<T>(self: Option<T>)
-- TODO: Return formatted enum variants too
return `{self.typeId}<T>` if self._optValue == nil then
end return `{self.typeId}::None`
}) else
return `{self.typeId}::Some({self._optValue})`
end
end,
}
)
end end
return { return {
-- TODO: Implement Option utility methods -- TODO: Implement Option utility methods
Option = Option, Option = Option,
Some = Some, Some = Some,
None = None None = None,
} }

View file

@ -30,14 +30,14 @@ function Result.new<T, E>(val: T, err: E)
__index = Result, __index = Result,
__tostring = function<T, E>(self: Result<T, E>) __tostring = function<T, E>(self: Result<T, E>)
if self:isOk() then if self:isOk() then
return `{self.typeId}::Ok<{self._value}>` return `{self.typeId}::Ok({self._value})`
end end
if self:isErr() then if self:isErr() then
return `{self.typeId}::Err<{self._error}>` return `{self.typeId}::Err({self._error})`
end end
return `{self.typeId}}<T, E>` return `{self.typeId}<T, E>`
end, end,
__eq = function<T, E>(self: Result<T, E>, other: Result<T, E>) __eq = function<T, E>(self: Result<T, E>, other: Result<T, E>)
if if
@ -267,7 +267,7 @@ function Result.transpose<T, E>(self: Result<Option<T>, E>): Option<Result<T, E>
return None() return None()
elseif self:isOkAnd(function(val): boolean elseif self:isOkAnd(function(val): boolean
return val._optValue == nil return val._optValue == nil
end) ~= nil then end) then
return Some(Ok(self._value._optValue)) return Some(Ok(self._value._optValue))
elseif self:isErr() then elseif self:isErr() then
return Some(Err(self._error)) return Some(Err(self._error))
@ -275,3 +275,15 @@ function Result.transpose<T, E>(self: Result<Option<T>, E>): Option<Result<T, E>
error("`Result` is not transposable") error("`Result` is not transposable")
end end
local x: Result<Option<string>, string> = Ok(None())
print(tostring(x))
return {
Ok = Ok,
Err = Err,
Result = Result,
}
-- print(y:transpose()) -- this should have a typeerror, i need to fix this

20
test.luau Normal file
View file

@ -0,0 +1,20 @@
local result = require("lib/result")
type Result<T, E> = result.Result<T, E>
local Ok = result.Ok
local Err = result.Err
local function canError(): Result<number, string>
if math.round(math.random()) == 1 then
return Err("you DIED")
end
return Ok(69)
end
function main()
local val = canError():unwrap()
print("got value: ", val)
end
return main()