https://github.com/baethon/union.php
Union type for PHP
https://github.com/baethon/union.php
Last synced: 1 day ago
JSON representation
Union type for PHP
- Host: GitHub
- URL: https://github.com/baethon/union.php
- Owner: baethon
- License: mit
- Created: 2018-07-20T16:06:20.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2020-08-24T13:02:24.000Z (over 4 years ago)
- Last Synced: 2025-02-16T21:18:10.282Z (3 months ago)
- Language: PHP
- Size: 31.3 KB
- Stars: 2
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# baethon/union
Provides utilities to define tagged unions.
# Tagged unions?
I'm not good with words, yet folks from [Folktale](https://folktale.origamitower.com/api/v2.1.0/en/folktale.adt.union.html) describe it nicely:
> Modelling data is important for a range of reasons. From performance to correctness to safety. Tagged unions give you a way of modelling choices that forces the correct handling of them, unlike predicate-based branching, such as the one used by if statements and other common control flow structures.
# Installation
```bash
composer require baethon/union
```# Usage
To create a tag union it's required to create a class which extends `Baethon\Union\AbstractUnion`.
```php
class Maybe extends \Baethon\Union\AbstractUnion
{
}
```Also you need to define tags which will represent state of the union.
```php
class Maybe extends \Baethon\Union\AbstractUnion
{
const SOME = 'Some:x';const NONE = 'None';
}
```## Signatures
Each tag has a definition (called _signature_), which can be defined using following syntax:
```
{Name}[:[param1[, param2[, ...[, paramN]]]]]
```Parameters define whether a tag will hold any value(s) (called _arguments_). They're optional.
## Working with unions
Union can be invoked using static constructor:
```php
$some = Maybe::Some(1);
```To work with the state of the union you should use `matchWith()`. It will return the value returned by the matching callback:
```php
function addTen(Maybe $maybe) {
return $maybe->matchWith([
'Some' => function ($x) {
return $x + 10;
},
'None' => function () {
throw new \Exception('Sorry, can\'t add a number to nothing');
}
]);
}addTen($some); // 11
````matchWith()` will check if all possible branches are mapped:
* if a tag is not covered by map `UnderflowException` will be thrown
* if map covers more tags than defined ones it will throw 'OverflowException'.It's possible to use wildcard map to cover all other cases:
```php
$some->matchWith([
'*' => function () {
return 100;
}
]); // 100
```You can use defined const values in mapping:
```php
$some->matchWith([
Maybe::SOME => function () {},
Maybe::NONE => function () {}
]);
```# Testing
```
./vendor/bin/phpunit
```