# Result

## Overview

Normally, to represent a successful result, you'd just return it directly from a function or a method and to represent an error you'd use exceptions. However, exceptions are not ideal in cases where "an error is expected".

Instead of throwing exceptions, you can use `Result::error()` to represent recoverable errors and for successful results `Result::ok()`. The main insiprations are C++23 `std::expected` and Rust's `Result`.

### API

**`static function ok(T $value = null): Result<T, E>`**

Returns a result with an ok value.&#x20;

```php
Result::ok(2);
```

**`static function error(E $value): Result<T, E>`**

Returns a result with an error value.&#x20;

```php
Result::error(3);
```

**`function isOk(): bool`**

Returns true if the result is ok.

```php
assert(true === Result::ok(2)->isOk());
assert(false === Result::error(2)->isOk());
```

**`function equals(Result<T, E> $other): bool`**

Returns true if this result equals another result.

```php
assert(true === Result::ok(2)->equals(Result::ok(2)));
assert(true === Result::error(3)->equals(Result::error(3)));
assert(false === Result::ok(2)->equals(Result::ok('2')));
assert(false === Result::ok(2)->equals(Result::error(2)));
```

**`function map<U>(callable(T): U $fn): U`**

If the result has value, it maps its value using the provided `$fn` callback. Otherwise, returns the untouched result.

```php
function mul(int $value): int { return 3 * $value; }

assert(6 === Result::ok(2)->map('mul'));
assert(2 === Result::error(2)->map('mul'));
```

**`function mapError<U>(callable(E): U $fn): U`**

If the result has error, it maps its value using the provided `$fn` callback. Otherwise, returns the untouched result.

```php
function mul(int $value): int { return 3 * $value; }

assert(2 === Result::ok(2)->mapError('mul'));
assert(6 === Result::error(2)->mapError('mul'));
```

**`function valueOr<U>(U $value): T|U`**

Returns the contained value or the provided value on error.

```php
assert(2 === Result::ok(2)->valueOr(3));
assert(3 === Result::error(1)->valueOr(3));
```

#### Accessing the contained value and error

In case the `Result` has a value you can access it in two ways:

**By deferencing (shorter)**

```php
$r = Result::ok(2);
assert(2 === $r());
```

And normally by calling its `value` which is equivalent to dereferencing:

```php
$r = Result::ok(2);
assert(2 === $r->value);
```

If you try to reach for the contained value when is not present (the `Result` has an error) you'll get an exception:

```php
$r = Result::error(2);
$r->value; // or $r() -> throws \LogicException
```

To access an error:

```php
$r = Result::error(2);
assert(2 === $r->error);
```

And the same rules applies when accessing an error when is not present (the `Result` has a value).

```php
$r = Result::ok(2);
$r->error; // throws \LogicException
```
