<?php #BlackLivesMatter - github.com/ghostwriter namespace PolynomialFunctors; use InvalidArgumentException; /** * Represents a polynomial functor of the form `1 + x + x^2`. * * @template T * @implements Functor<T> */ final class Polynomial implements Functor { private int $tag; private mixed $value; private function __construct(int $tag, mixed $value = null) { $this->tag = $tag; $this->value = $value; } /** * Represents the `1` case. * * @return self */ public static function unit(): self { return new self(0); } /** * Represents the `x` case with one value. * * @template T * @param T $value * @return self<T> */ public static function linear(mixed $value): self { return new self(1, $value); } /** * Represents the `x^2` case with two values. * * @template T * @param T $first * @param T $second * @return self<T> */ public static function quadratic(mixed $first, mixed $second): self { return new self(2, [$first, $second]); } /** * Maps a function over the polynomial structure. * * @template A * @template B * @param callable(A): B $f * @return self<B> */ public function map(callable $f): Polynomial { return match ($this->tag) { 0 => self::unit(), 1 => self::linear($f($this->value)), 2 => self::quadratic($f($this->value[0]), $f($this->value[1])), default => throw new InvalidArgumentException('Unknown polynomial tag') }; } } interface Functor { /** * Maps a function over the functor. * * @template A * @template B * @param callable(A): B $f * @return Functor<B> */ public function map(callable $f): Functor; } $unit = Polynomial::unit(); // Represents `1` $linear = Polynomial::linear(5); // Represents `x` $quadratic = Polynomial::quadratic(3, 7); // Represents `x^2` // Mapping over the functor $mappedLinear = $linear->map(fn(int $x): int => $x * 2); // Maps over the single value $mappedQuadratic = $quadratic->map(fn(int $x): int => $x + 1); // Maps over both values // Output results var_dump($unit); // Nothing to map var_dump($mappedLinear); // Polynomial with value 10 var_dump($mappedQuadratic); // Polynomial with values 4 and 8
You have javascript disabled. You will not be able to edit any code.