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