···27272828## Methods
29293030-### Some
3131-3232-Creates a `some` Option
3333-3434-```php
3535-public static Some(\Ciarancoza\OptionResult\T $value = true): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\T>
3636-```
3737-3838-* This method is **static**.
3939-**Parameters:**
4040-4141-| Parameter | Type | Description |
4242-|-----------|--------------------------------|-------------|
4343-| `$value` | **\Ciarancoza\OptionResult\T** | |
4444-4545-***
4646-4747-### None
4848-4949-Creates a `none` Option
5050-5151-```php
5252-public static None(): \Ciarancoza\OptionResult\Option<never>
5353-```
5454-5555-* This method is **static**.
5656-***
5757-5830### __construct
59316032```php
···70427143***
72447373-### isSome
7474-7575-Returns `true` if the option is a `some` option.
7676-7777-```php
7878-public isSome(): bool
7979-```
8080-8181-***
8282-8383-### isNone
8484-8585-Returns `true` if the option is a `none` option.
8686-8787-```php
8888-public isNone(): bool
8989-```
9090-9191-***
9292-9345### and
94469595-Returns `$and` if `some`, otherwise returns `none`
4747+Returns `None` if the option is `None`, otherwise returns `$optb`
96489749```php
9898-public and(\Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\V> $and): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\V>
5050+public and(\Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U> $optb): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U>
9951```
1005210153**Parameters:**
1025410355| Parameter | Type | Description |
10456|-----------|-----------------------------------------------------------------|-------------|
105105-| `$and` | **\Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\V>** | |
5757+| `$optb` | **\Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U>** | |
1065810759***
1086010961### andThen
11062111111-Calls `$then` on contained value and returns if `some`, otherwise returns `none`
6363+Returns `None` if the option is `None`, otherwise calls `$f` with the wrapped value and returns the result.
1126411365```php
114114-public andThen(callable $then): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U>
6666+public andThen(callable $f): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U>
11567```
1166811769**Parameters:**
11870119119-| Parameter | Type | Description |
120120-|-----------|--------------|---------------------------------|
121121-| `$then` | **callable** | Function to transform the value |
7171+| Parameter | Type | Description |
7272+|-----------|--------------|-------------|
7373+| `$f` | **callable** | |
1227412375***
1247612577### expect
12678127127-Throws UnwrapNoneException with a custom error message if `none`, otherwise returns the inner value
7979+Returns the contained `Some` value, or throws UnwrapNoneException if the value is `None` with a custom panic message provided by `$msg`.
1288012981```php
13082public expect(string $msg): \Ciarancoza\OptionResult\T
···1449614597### filter
14698147147-Returns `None` if the option is `None`, otherwise calls `predicate` with the wrapped value and returns:
148148-- `Some(T)` if `predicate` returns `true`, and
9999+Returns `None` if the option is `None`, otherwise calls `$predicate` with the wrapped value and returns:
100100+- `Some(T)` if `predicate` returns `true` (where `t` is the wrapped value and
149101- `None` if `predicate` returns `false`
150102151103```php
152152-public filter(callable $predicate): self
104104+public filter(callable $predicate): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\T>
153105```
154106155107**Parameters:**
···162114163115### inspect
164116165165-Calls a function on the contained value if `Some`. Returns the original option in either case.
117117+Calls a function with a reference to the contained value if `Some`
166118167119```php
168168-public inspect(callable $fn): self
120120+public inspect(callable $f): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\T>
169121```
170122171123**Parameters:**
172124173125| Parameter | Type | Description |
174126|-----------|--------------|-------------|
175175-| `$fn` | **callable** | |
127127+| `$f` | **callable** | |
176128177129***
178130179179-### unwrap
131131+### isNone
180132181181-Returns the contained value if `some`, otherwise throws UnwrapNoneException.
133133+Returns `true` of the option is a `None` value
182134183135```php
184184-public unwrap(): \Ciarancoza\OptionResult\T
136136+public isNone(): bool
185137```
186138187187-**Return Value:**
139139+***
188140189189-The contained value
141141+### isSome
190142191191-**Throws:**
143143+Returns `true` of the option is a `Some` value
192144193193-When called on `None`
194194-- [`UnwrapNoneException`](./Exceptions/UnwrapNoneException)
145145+```php
146146+public isSome(): bool
147147+```
195148196149***
197150198198-### unwrapOr
151151+### map
199152200200-Returns the contained `some` value or a provided default.
153153+Maps an `Option<T>` to `Option<U>` by applying a function to a contained value (if `Some`) or returns `None` (if `None`)
201154202155```php
203203-public unwrapOr(\Ciarancoza\OptionResult\V $or): \Ciarancoza\OptionResult\T|\Ciarancoza\OptionResult\V
156156+public map(callable $f): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U>
204157```
205158206159**Parameters:**
207160208208-| Parameter | Type | Description |
209209-|-----------|--------------------------------|-------------|
210210-| `$or` | **\Ciarancoza\OptionResult\V** | |
161161+| Parameter | Type | Description |
162162+|-----------|--------------|-------------|
163163+| `$f` | **callable** | |
211164212165***
213166214214-### map
167167+### mapOr
215168216216-Calls `fn` on contained value if `some`, returns `none` if `none`
169169+Returns the provided default (if none), or applies a function to the contained value (if any).
217170218171```php
219219-public map(callable $fn): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U>
172172+public mapOr(\Ciarancoza\OptionResult\V $or, callable $f): \Ciarancoza\OptionResult\U|\Ciarancoza\OptionResult\V
220173```
221174222175**Parameters:**
223176224224-| Parameter | Type | Description |
225225-|-----------|--------------|---------------------------------|
226226-| `$fn` | **callable** | Function to transform the value |
177177+| Parameter | Type | Description |
178178+|-----------|--------------------------------|-------------|
179179+| `$or` | **\Ciarancoza\OptionResult\V** | |
180180+| `$f` | **callable** | |
227181228182***
229183230230-### mapOr
184184+### None
231185232232-Calls `fn` on a contained value if `some`, or returns $or if `none`
186186+Creates a `none` Option
233187234188```php
235235-public mapOr(mixed $or, callable $fn): \Ciarancoza\OptionResult\V|\Ciarancoza\OptionResult\U
189189+public static None(): \Ciarancoza\OptionResult\Option<never>
236190```
237191238238-**Parameters:**
239239-240240-| Parameter | Type | Description |
241241-|-----------|--------------|---------------------------------|
242242-| `$or` | **mixed** | |
243243-| `$fn` | **callable** | Function to transform the value |
244244-192192+* This method is **static**.
245193***
246194247195### reduce
248196197197+Reduces two options into one, using the provided function if both are `Some`.
198198+249199```php
250250-public reduce(self $other, callable $fn): self
200200+public reduce(\Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\V> $other, callable $f): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\U|\Ciarancoza\OptionResult\T|\Ciarancoza\OptionResult\V>
251201```
252202203203+If `$this` is `Some(s)` and `$other` is `Some(o)`, this method returns `Some($f(s,o))`.
204204+Otherwise, if only one of `$this` and `$other` is `Some`, that one is returned.
205205+If both `$this` and `$other` are `None`, `None` is returned.
206206+253207**Parameters:**
254208255255-| Parameter | Type | Description |
256256-|-----------|--------------|-------------|
257257-| `$other` | **self** | |
258258-| `$fn` | **callable** | |
209209+| Parameter | Type | Description |
210210+|-----------|-----------------------------------------------------------------|-------------|
211211+| `$other` | **\Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\V>** | |
212212+| `$f` | **callable** | |
259213260214***
261215262262-### replace
216216+### Some
217217+218218+Creates a `some` Option
263219264220```php
265265-public replace(mixed $value): self
221221+public static Some(\Ciarancoza\OptionResult\T $value = true): \Ciarancoza\OptionResult\Option<\Ciarancoza\OptionResult\T>
266222```
267223224224+* This method is **static**.
268225**Parameters:**
269226270270-| Parameter | Type | Description |
271271-|-----------|-----------|-------------|
272272-| `$value` | **mixed** | |
227227+| Parameter | Type | Description |
228228+|-----------|--------------------------------|-------------|
229229+| `$value` | **\Ciarancoza\OptionResult\T** | |
273230274231***
275232276276-### take
233233+### unwrap
234234+235235+Returns the contained `Some` value or throws UnwrapNoneException
277236278237```php
279279-public take(): self
238238+public unwrap(): \Ciarancoza\OptionResult\T
280239```
281240241241+**Throws:**
242242+243243+- [`UnwrapNoneException`](./Exceptions/UnwrapNoneException)
244244+282245***
283246284284-### takeIf
247247+### unwrapOr
248248+249249+Returns the contained `some` value or a provided default.
285250286251```php
287287-public takeIf(callable $predicate): \Ciarancoza\OptionResult\Option
252252+public unwrapOr(\Ciarancoza\OptionResult\V $or): \Ciarancoza\OptionResult\T|\Ciarancoza\OptionResult\V
288253```
289254290255**Parameters:**
291256292292-| Parameter | Type | Description |
293293-|--------------|--------------|-------------|
294294-| `$predicate` | **callable** | |
257257+| Parameter | Type | Description |
258258+|-----------|--------------------------------|-------------|
259259+| `$or` | **\Ciarancoza\OptionResult\V** | |
295260296261***
+115-144
src/Option.php
···1313class Option
1414{
1515 /**
1616- * Creates a `some` Option
1717- *
1818- * @template T
1616+ * @nodoc
1917 *
2018 * @param T $value
2121- * @return Option<T>
2219 */
2323- public static function Some(mixed $value = true): static
2424- {
2525- if ($value === null) {
2626- return self::None();
2727- }
2828-2929- return new static($value, true);
3030- }
3131-3232- /**
3333- * Creates a `none` Option
3434- *
3535- * @return Option<never>
3636- */
3737- public static function None(): static
3838- {
3939- return new static(null, false);
4040- }
4141-4242- /** @param T $value */
4320 private function __construct(
4421 private mixed $value,
4522 private bool $isSome
4623 ) {}
47244848- /** Returns `true` if the option is a `some` option. */
4949- public function isSome(): bool
5050- {
5151- return $this->isSome;
5252- }
5353-5454- /** Returns `true` if the option is a `none` option. */
5555- public function isNone(): bool
5656- {
5757- return ! $this->isSome();
5858- }
5959-6025 /**
6161- * Returns `$and` if `some`, otherwise returns `none`
2626+ * Returns `None` if the option is `None`, otherwise returns `$optb`
6227 *
6363- * @template V
2828+ * @template U
6429 *
6565- * @param Option<V> $and
6666- * @return Option<V>
3030+ * @param Option<U> $optb
3131+ * @return Option<U>
6732 */
6868- public function and(self $and): Option
3333+ public function and(self $optb): Option
6934 {
7070- return match (true) {
7171- $this->isSome() => $and,
7272- $this->isNone() => self::None(),
7373- };
3535+ if ($this->isSome()) {
3636+ return $optb;
3737+ }
3838+3939+ return static::None();
7440 }
75417642 /**
7777- * Calls `$then` on contained value and returns if `some`, otherwise returns `none`
4343+ * Returns `None` if the option is `None`, otherwise calls `$f` with the wrapped value and returns the result.
7844 *
7945 * @template U
8046 *
8181- * @param callable(T): Option<U> $then Function to transform the value
4747+ * @param callable(T): Option<U> $f
8248 * @return Option<U>
8349 */
8484- public function andThen(callable $then): Option
5050+ public function andThen(callable $f): Option
8551 {
8686- return match (true) {
8787- $this->isSome() => $then($this->unwrap()),
8888- $this->isNone() => self::None(),
8989- };
5252+ if ($this->isSome()) {
5353+ return $f($this->unwrap());
5454+ }
5555+5656+ return static::None();
9057 }
91589259 /**
9393- * Throws UnwrapNoneException with a custom error message if `none`, otherwise returns the inner value
9494- *
6060+ * Returns the contained `Some` value, or throws UnwrapNoneException if the value is `None` with a custom panic message provided by `$msg`.
9561 *
9662 * @return T
9763 *
···10773 }
1087410975 /**
110110- * Returns `None` if the option is `None`, otherwise calls `predicate` with the wrapped value and returns:
111111- * - `Some(T)` if `predicate` returns `true`, and
7676+ * Returns `None` if the option is `None`, otherwise calls `$predicate` with the wrapped value and returns:
7777+ * - `Some(T)` if `predicate` returns `true` (where `t` is the wrapped value and
11278 * - `None` if `predicate` returns `false`
11379 *
11480 * @param callable(T): bool $predicate
8181+ * @return Option<T>
11582 */
11683 public function filter(callable $predicate): self
11784 {
11885 if ($this->isSome() && $predicate($this->unwrap())) {
119119- return $this;
8686+ return static::Some($this->unwrap());
12087 }
12188122122- return self::None();
8989+ return static::None();
12390 }
1249112592 /**
126126- * Calls a function on the contained value if `Some`. Returns the original option in either case.
9393+ * Calls a function with a reference to the contained value if `Some`
12794 *
128128- * @param callable(T) $fn
9595+ * @param callable(T): void $f
9696+ * @return Option<T>
12997 */
130130- public function inspect(callable $fn): self
9898+ public function inspect(callable $f): self
13199 {
132100 if ($this->isSome()) {
133133- $fn($this->unwrap());
101101+ $f($this->unwrap());
102102+103103+ return static::Some($this->unwrap());
134104 }
135105136136- return $this;
106106+ return static::None();
107107+ }
108108+109109+ /**
110110+ * Returns `true` of the option is a `None` value
111111+ */
112112+ public function isNone(): bool
113113+ {
114114+ return ! $this->isSome();
137115 }
138116139117 /**
140140- * Returns the contained value if `some`, otherwise throws UnwrapNoneException.
118118+ * Returns `true` of the option is a `Some` value
119119+ */
120120+ public function isSome(): bool
121121+ {
122122+ return $this->isSome;
123123+ }
124124+125125+ /**
126126+ * Maps an `Option<T>` to `Option<U>` by applying a function to a contained value (if `Some`) or returns `None` (if `None`)
141127 *
142142- * @return T The contained value
128128+ * @template U
143129 *
144144- * @throws UnwrapNoneException When called on `None`
130130+ * @param callable(T): U $f
131131+ * @return Option<U>
145132 */
146146- public function unwrap(): mixed
133133+ public function map(callable $f): self
147134 {
148148- if ($this->isNone()) {
149149- throw new UnwrapNoneException;
135135+ if ($this->isSome()) {
136136+ return static::Some($f($this->value));
150137 }
151138152152- return $this->value;
139139+ return static::None();
140140+153141 }
154142155143 /**
156156- * Returns the contained `some` value or a provided default.
144144+ * Returns the provided default (if none), or applies a function to the contained value (if any).
145145+ *
146146+ * @template U
147147+ * @template V
157148 *
158149 * @param V $or
159159- * @return T|V
150150+ * @param callable(T): U $f
151151+ * @return U|V
160152 */
161161- public function unwrapOr(mixed $or): mixed
153153+ public function mapOr(mixed $or, callable $f): mixed
162154 {
163155 if ($this->isSome()) {
164164- return $this->unwrap();
156156+ return $f($this->unwrap());
165157 }
166158167159 return is_callable($or) ? $or() : $or;
168160 }
169161170162 /**
171171- * Calls `fn` on contained value if `some`, returns `none` if `none`
172172- *
173173- * @template U
163163+ * Creates a `none` Option
174164 *
175175- * @param callable(T): U $fn Function to transform the value
176176- * @return Option<U>
165165+ * @return Option<never>
177166 */
178178- public function map(callable $fn): self
167167+ public static function None(): static
179168 {
180180- if ($this->isNone()) {
181181- return self::None();
182182- }
183183-184184- return self::Some($fn($this->value));
169169+ return new static(null, false);
185170 }
186171187172 /**
188188- * Calls `fn` on a contained value if `some`, or returns $or if `none`
173173+ * Reduces two options into one, using the provided function if both are `Some`.
189174 *
190190- * @template V $or
175175+ * If `$this` is `Some(s)` and `$other` is `Some(o)`, this method returns `Some($f(s,o))`.
176176+ * Otherwise, if only one of `$this` and `$other` is `Some`, that one is returned.
177177+ * If both `$this` and `$other` are `None`, `None` is returned.
178178+ *
179179+ * @template V
191180 * @template U
192181 *
193193- * @param callable(T): U $fn Function to transform the value
194194- * @return V|U
182182+ * @param Option<V> $other
183183+ * @param callable(T, V): U $f
184184+ * @return Option<U|T|V>
195185 */
196196- public function mapOr(mixed $or, callable $fn): mixed
197197- {
198198- return match (true) {
199199- $this->isSome() => $fn($this->unwrap()),
200200- $this->isNone() => is_callable($or) ? $or() : $or,
201201- };
202202- }
203203-204204- /*
205205- * Reduces to options into one, using the provided function if both are `some`
206206- *
207207- * @template U
208208- * @template R
209209- * @param Option<U> $other
210210- * @param callable(T, U): R $fn
211211- * @return Option<T|U|R>
212212- */
213213- public function reduce(self $other, callable $fn): self
186186+ public function reduce(self $other, callable $f): self
214187 {
215188 return match (true) {
216216- $this->isSome() && $other->isSome() => self::Some($fn($this->unwrap(), $other->unwrap())),
189189+ $this->isSome() && $other->isSome() => static::Some($f($this->unwrap(), $other->unwrap())),
217190 $this->isSome() => $this,
218191 $other->isSome() => $other,
219219- default => self::None(),
192192+ default => static::None(),
220193 };
221194 }
222195223223- /*
224224- * Replaces the actual value in the option by the value given in the parameter, returning the old value if present
225225- *
226226- * @template NT
227227- *
228228- * @return Option<T>
229229- */
230230- public function replace(mixed $value): self
196196+ /**
197197+ * Creates a `some` Option
198198+ *
199199+ * @template T
200200+ *
201201+ * @param T $value
202202+ * @return Option<T>
203203+ */
204204+ public static function Some(mixed $value = true): static
231205 {
232232- $old = clone $this;
233233- if ($this->isNone() && $value !== null) {
234234- $this->isSome = true;
206206+ if ($value === null) {
207207+ return static::None();
235208 }
236236- $this->value = $value;
237209238238- return $old;
210210+ return new static($value, true);
239211 }
240212241241- /*
242242- * Takes the value out of the option, leaving a `None` in its place
243243- *
244244- * return Option<T>
245245- */
246246- public function take(): self
213213+ /**
214214+ * Returns the contained `Some` value or throws UnwrapNoneException
215215+ *
216216+ * @return T
217217+ *
218218+ * @throws UnwrapNoneException
219219+ */
220220+ public function unwrap(): mixed
247221 {
248248- $old = clone $this;
249249- $this->value = null;
250250- $this->isSome = false;
222222+ if ($this->isNone()) {
223223+ throw new UnwrapNoneException;
224224+ }
251225252252- return $old;
226226+ return $this->value;
253227 }
254228255255- /*
256256- * Takes the value out of the option, but only if the predicate evaluates to `true`.
229229+ /**
230230+ * Returns the contained `some` value or a provided default.
257231 *
258258- * @param callable(T): bool $predicate
259259- * @return Option<T>
260260- */
261261- public function takeIf(callable $predicate): Option
232232+ * @param V $or
233233+ * @return T|V
234234+ */
235235+ public function unwrapOr(mixed $or): mixed
262236 {
263263- if ($this->isNone()) {
264264- return self::None();
265265- }
266266- if ($predicate($this->value)) {
267267- return $this->take();
237237+ if ($this->isSome()) {
238238+ return $this->unwrap();
268239 }
269240270270- return self::None();
241241+ return is_callable($or) ? $or() : $or;
271242 }
272243}