Skip to content

Instantly share code, notes, and snippets.

@assertchris
Last active October 26, 2024 09:32
Show Gist options
  • Save assertchris/cbe34a6b9ede1457424efe86692b366e to your computer and use it in GitHub Desktop.
Save assertchris/cbe34a6b9ede1457424efe86692b366e to your computer and use it in GitHub Desktop.
Monads talk examples
<?php
abstract class Named {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
class Country extends Named {
public $province;
public function __construct($name, $province = null) {
parent::__construct($name);
$this->province = $province;
}
}
class Province extends Named {
public $city;
public function __construct($name, $city = null) {
parent::__construct($name);
$this->city = $city;
}
}
class City extends Named {}
function getCityFromCountry(Country $country) {
return $country
->province
->city;
}
$city = new City('Cape Town');
$province = new Province('Western Cape', $city);
$country = new Country('South Africa', $province);
var_dump(getCityFromCountry($country));
<?php
class Genre {
public function __construct(
public string $name,
public array $authors,
) {}
}
class Author {
public function __construct(
public string $name,
public array $books,
) {}
}
class Book {
public function __construct(
public string $name,
public string $content,
) {}
}
function flatMap(array $items, Closure $mapper) {
return array_merge(
...array_map($mapper, $items),
);
}
function getAllWordsFor(array $genres) {
return flatMap(
$genres,
fn(Genre $genre) => flatMap(
$genre->authors,
fn(Author $author) => flatMap(
$author->books,
fn(Book $book) => array_map(fn($word) => trim($word), explode(' ', $book->content)),
),
),
);
// return (new Many($genres))
// ->then(fn($genre) => $genre->authors)
// ->then(fn($author) => $author->books)
// ->then(fn($book) => explode(' ', $book->content))
// ->value();
// return (new Many($genres))
// ->authors
// ->books
// ->then(fn($book) => explode(' ', $book->content))
// ->value();
}
// class Many {
// public function __construct(
// private array $value = [],
// ) {}
// public function then(Closure $mapper) {
// return new self(flatMap($this->value, $mapper));
// }
// public function value() {
// return $this->value;
// }
// public function __get(string $name) {
// return $this->then(fn($item) => $item->$name);
// }
// }
$genres = [
new Genre('Science Fiction', [
new Author('Douglas Adams', [
new Book(
'Hitchhiker\'s Guide To The Galaxy',
'In the beginning the Universe was created. This
has made a lot of people very angry and been widely
regarded as a bad move...',
),
]),
]),
];
var_dump(array_filter(getAllWordsFor($genres)));
<?php
class Config {
private string $appName;
private string $timeZone;
public function appName(string $value = null) {
if (is_null($value)) {
return $this->appName;
}
$this->appName = $value;
return $this;
}
public function timeZone(string $value = null) {
if (is_null($value)) {
return $this->timeZone;
}
$this->timeZone = $value;
return $this;
}
// public function __call($name, array $parameters) {
// if (property_exists($this, $name)) {
// if (is_null($name)) {
// return $this->$name;
// }
// $this->$name = $parameters[0];
// }
// return $this;
// }
}
class Fluent {
public function __construct(private $decorated) {}
public function then($name, $value = null) {
return (function() use ($name, $value) {
if (property_exists($this, $name)) {
if (is_null($value)) {
return $this->$name;
}
$this->$name = $value;
}
return new Fluent($this);
})->call(clone $this->decorated);
}
public function value() {
return $this->decorated;
}
// public function __call($name, array $parameters) {
// return $this->then($name, ...$parameters);
// }
}
$config = new Config();
$config->appName('testing');
$config->timeZone('CET');
// $config = (new Fluent(new Config));
// $config = $config->then('appName', 'testing');
// $config = $config->then('timeZone', 'CET');
// $config = (new Fluent(new Config));
// $config = $config->appName('testing');
// $config = $config->timeZone('CET');
var_dump($config);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment