aboutsummaryrefslogtreecommitdiff
path: root/std/prelude/results.pk
diff options
context:
space:
mode:
Diffstat (limited to 'std/prelude/results.pk')
-rw-r--r--std/prelude/results.pk112
1 files changed, 55 insertions, 57 deletions
diff --git a/std/prelude/results.pk b/std/prelude/results.pk
index 81bccf0..61b0c8a 100644
--- a/std/prelude/results.pk
+++ b/std/prelude/results.pk
@@ -8,8 +8,8 @@ pub type Result[T, E] = union
Okay(T)
Error(E)
-## The Err interface. Useful for dynamically dispatching errors.
-pub type Err = interface
+## The Err class. Useful for dynamically dispatching errors.
+pub type Err = class
str(Self): str
dbg(Self): str
@@ -18,7 +18,21 @@ pub type Err = interface
pub type Result[T] = Result[T, ref Err]
## A `Result` type that only checks for success.
## Does not contain a value.
-pub type Success[E] = Result[Unit, E]
+# pub type Success[E] = Result[void, E]
+## A `Result` type that only checks for success.
+## Does not contain a value. Dynamically dispatched.
+# pub type Success = Result[void]
+
+## Syntactic sugar for dynamic result type declarations.
+pub macro !(T: type) =
+ quote Result[`T`]
+
+## Indirect access. Propagates `Error`.
+pub macro ?[T, E](self: Result[T, E]) =
+ quote
+ match `self`
+ of Okay(x) then x
+ of Error(e) then return Error(e)
## Checks if a `Result` type was successful.
pub func is_ok[T, E](self: Result[T, E]): bool =
@@ -28,110 +42,94 @@ pub func is_err[T, E](self: Result[T, E]): bool =
self of Error(_)
## Converts from a `Result[T, E]` to an `Option[T]`.
-pub func ok[T, E](self: Result[T, E]): Option[T] =
- if self of Okay(x):
+pub func ok[T, E](self: Result[T, E]): T? =
+ if self of Okay(x) then
Some(x)
- else:
- None()
+ else
+ None
## Converts from a `Result[T, E]` to an `Option[E]`.
-pub func err[T, E](self: Result[T, E]): Option[E] =
- if self of Error(x):
+pub func err[T, E](self: Result[T, E]): E? =
+ if self of Error(x) then
Some(x)
- else:
- None()
+ else
+ None
## Applies a function to `T`, if self is `Okay`.
pub func map[T, E, U](self: Result[T, E], fn: T -> U): Result[U, E] =
match self
- of Okay(x):
+ of Okay(x) then
Okay(fn(x))
- of Error(e):
+ of Error(e) then
Error(e)
## Applies a function to `E`, if self is `Error`.
pub func map_err[T, E, F](self: Result[T, E], fn: E -> F): Result[T, F] =
match self
- of Error(e):
+ of Error(e) then
Error(fn(e))
- of Okay(x):
+ of Okay(x) then
Okay(x)
## Applies a function to `T`, if it exists. Equivalent to `self.map(fn).flatten`.
pub func flatmap[T, E, U](self: Result[T, E], fn: T -> Result[U, E]): Result[U, E] =
match self
- of Okay(x):
+ of Okay(x) then
fn(x)
- of Error(e):
+ of Error(e) then
Error(e)
## Converts from a `Result[Result[T, E], E]` to a `Result[T, E]`.
pub func flatten[T, E](self: Result[Result[T, E], E]): Result[T, E] =
match self
- of Okay(Okay(x)):
+ of Okay(Okay(x)) then
Okay(x)
- of Okay(Error(e)), Error(e):
+ of Okay(Error(e)), Error(e) then
Error(e)
## Transposes a `Result[Option[T], E]` to an `Option[Result[T, E]]`.
-pub func transpose[T, E](self: Result[Option[T], E]): Option[Result[T, E]] =
+pub func transpose[T, E](self: Result[T?, E]): Result[T, E]? =
match self
- of Okay(Some(x)):
+ of Okay(Some(x)) then
Some(Okay(x))
- of Okay(None()), Error(_):
- None()
+ of Okay(None), Error(_) then
+ None
## Transposes an `Option[Result[T, E]]` to a `Result[Option[T], E]`. Takes a default error.
-pub func transpose[T, E](self: Option[Result[T, E]], error: E): Result[Option[T], E] =
+pub func transpose[T, E](self: Result[T, E]?, error: E): Result[T?, E] =
match self
- of Some(Okay(x)):
- Okay(Some(x))
- of Some(Error(e)):
- Error(e)
- of None():
- Error(error)
+ of Some(Okay(x)) then Okay(Some(x))
+ of Some(Error(e)) then Error(e)
+ of None then Error(error)
## Returns the inner value or a default.
pub func get_or[T, E](self: Result[T, E], default: T): T =
- if self of Okay(x): x
- else: default
+ if self of Okay(x) then x
+ else default
## Directly accesses the inner value. Throws an exception if `Error`.
pub func ![T, E](self: Result[T, E]): T =
match self
- of Okay(x): x
- of Error(e): raise e
+ of Okay(x) then x
+ of Error(e) then raise e
## Directly accesses the inner error. Throws an exception of type T if `Okay`.
pub func get_err[T, E](self: Result[T, E]): E =
match self
- of Error(e): e
- of Okay(x): raise x
-
-## Indirect access. Propagates `Error`.
-pub macro ?[T, E](self: Result[T, E]) =
- quote:
- match `self`
- of Okay(x): x
- of Error(e): return Error(e)
-
-## Syntactic sugar for dynamic `Result` type declarations.
-pub macro ?!(T: type) =
- quote:
- Result[`T`]
+ of Error(e) then e
+ of Okay(x) then raise x
## Overloads the `==` operation for use on Results.
pub func ==[T, E, F](a: Result[T, E], b: Result[T, F]): bool =
- match (a, b)
- of (Okay(x), Okay(y)):
+ if (a, b) of (Okay(x), Okay(y)) then
x == y
- of _:
+ else
false
## Overloads the `str()` function for use on Results.
-pub func str[T, E](self: Result[T, E]): str =
+pub func str[T: Display, E: Display](self: Result[T, E]): str =
match self
- of Some(x):
- fmt("Okay({})", x.str)
- of Error(e):
- fmt("Error({})", e.str)
+ of Some(x) then
+ "Okay({})".fmt(x.str)
+ of Error(e) then
+ "Error({})".fmt(e.str)
-examples:
+examples
let x: Error("fuck") = Okay(42)
func idk: Result[int, string]