diff options
Diffstat (limited to 'std/prelude/options.pk')
-rw-r--r-- | std/prelude/options.pk | 97 |
1 files changed, 45 insertions, 52 deletions
diff --git a/std/prelude/options.pk b/std/prelude/options.pk index 4f6cef2..d5cfb9d 100644 --- a/std/prelude/options.pk +++ b/std/prelude/options.pk @@ -9,91 +9,84 @@ pub type Option[T] = union Some(T) None +## Syntactic sugar for optional type declarations. +pub macro ?(T: type) = + quote Option[`T`] + +## Directly accesses the inner value. Throws an exception if None. +pub func ![T](self: T?): T = + if self of Some(x) then x + else raise "empty" + +## Indirect access. Propagates `None`. +pub macro ?[T](self: T?) = + quote + match `self` + of Some(x) then x + of None then return None + ## Checks if a type is present within an `Option` type. -pub func is_some[T](self: Option[T]): bool = +pub func is_some[T](self: T?): bool = self of Some(_) ## Checks if a type is not present within an `Option` type. -pub func is_none[T](self: Option[T]): bool = +pub func is_none[T](self: T?): bool = self of None ## Converts an `Option[T]` to a `Result[T, E]` given a user-provided error. -pub func err[T, E](self: Option[T], error: E): Result[T, E] = - if self of Some(x): +pub func err[T, E](self: T?, error: E): Result[T, E] = + if self of Some(x) then Okay(x) - else: + else Error(error) ## Applies a function to `T`, if it exists. -pub func map[T, U](self: Option[T], fn: T -> U): Option[U] = - if self of Some(x): +pub func map[T, U](self: T?, fn: T -> U): U? = + if self of Some(x) then Some(fn(x)) - else: + else None ## Converts `T` to a `None`, if `fn` returns false and it exists. -pub func filter[T](self: Option[T], fn: T -> bool): Option[T] = - if self of Some(x) and fn(x): +pub func filter[T](self: T?, fn: T -> bool): T? = + if self of Some(x) and fn(x) then Some(x) - else: + else None ## Applies a function to T, if it exists. Equivalent to `self.map(fn).flatten`. -pub func flatmap[T, U](self: Option[T], fn: T -> Option[U]): Option[U] = - if self of Some(x): +pub func flatmap[T, U](self: T?, fn: T -> U?): U? = + if self of Some(x) then fn(x) - else: + else None ## Converts from Option[Option[T]] to Option[T]. -pub func flatten[T](self: Option[Option[T]]): Option[T] = - match self - of Some(Some(x)): +pub func flatten[T](self: T??): T? = + if self of Some(Some(x)) then Some(x) - of _: + else None ## Returns the inner value or a default. -pub func get_or[T](self: Option[T], default: T): T = - if self of Some(x): x - else: default - -## A dummy type signalling the empty value -type EmptyType = distinct unit - -## Directly accesses the inner value. Throws an exception if None. -pub func ![T](self: Option[T]): T = - if self of Some(x): x - else: raise EmptyType - -## Indirect access. Propagates `None`. -## Parsed by compiler magic. -pub macro ?[T](self: Option[T]) = - quote: - match `self` - of Some(x): x - of None: return None - -## Syntactic sugar for optional type declarations. -pub macro ?(T: type) = - quote: - Option[`T`] +pub func get_or[T](self: T?, default: T): T = + if self of Some(x) then x + else default ## Overloads the `==` operation for use on Options. -pub func ==[T](a, b: Option[T]): bool = - match (a, b) - of (Some(x), Some(y)): +pub func ==[T](a, b: T?): bool = + if (a, b) of (Some(x), Some(y)) then x == y - of _: + else false ## Overloads the `str()` function for use on Options. -pub func str[T](self: Option[T]): str = - if self of Some(x): - fmt("Some({})", x.str) - else: +pub func str[T: Display](self: T?): str = + if self of Some(x) then + "Some({})".fmt(x.str) + else "None" -examples: +examples let x = Some(42) - if x of Some(y): + if x of Some(y) then assert x! == y # references: |