diff options
Diffstat (limited to 'std/prelude/results.pk')
-rw-r--r-- | std/prelude/results.pk | 112 |
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] |