On Thu, May 27, 2021, at 8:23 AM, Rowan Tommins wrote:
> The combination of union types and enums actually gives a much more
> expressive way of representing "valid value or explicit null or special
> default". To use the ORM lazy-loading example:
>
>
> enum ORMState {
> case Unloaded;
> }
>
> class Example {
> private int|ORMState|null $foo = ORMState::Unloaded;
>
> public function getFoo(): ?int {
> if ( $this->foo === ORMState::Unloaded ) {
> $this->foo = $this->loadFromDatabase('foo');
> }
> return $this->foo;
> }
>
> private function loadFromDatabase($fieldName): ?int {
> echo "Fetching '$fieldName' from database...\n";
> return 42;
> }
> }
>
> // Create object; note there's no constructor, but the property has a
> default so is never uninitialized
> $obj = new Example;
> // On first call to method, the default value is detected and the
> property lazy-loaded
> var_dump($obj->getFoo());
> // Subsequent accesses return the loaded value directly, at the cost of
> a single strict comparison, no magic function needed
> var_dump($obj->getFoo());
I had not thought of this use of Enums, but I love it. It's not as elegant as
a tagged enum for a monad, but it gets you 80% of the way there. Especially if
you combine it with match().
enum Result {
case None;
}
function find_user(int $id): User|Result { ... }
$user = match($u = find_user($id)) {
Result::None => some error handling,
default: $u,
};
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php