Skip to content

Commit c8e1424

Browse files
authored
Merge pull request #5 from endou-mame:endou-mame/issue4
Add: Monad interface and Option types.
2 parents 7a65a28 + 5264aa1 commit c8e1424

File tree

4 files changed

+132
-0
lines changed

4 files changed

+132
-0
lines changed

src/Monad.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EndouMame\PhpMonad;
6+
7+
use Closure;
8+
9+
/**
10+
* @template T
11+
*/
12+
interface Monad
13+
{
14+
/**
15+
* @template T2
16+
* @param Closure(T):static<T2> $f
17+
* @return static<T2>
18+
*/
19+
public function bind(Closure $f): self;
20+
21+
/**
22+
* @template TValue
23+
* @param TValue $value
24+
* @return static<TValue>
25+
*/
26+
public static function unit(mixed $value): self;
27+
}

src/Option.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EndouMame\PhpMonad;
6+
7+
use EndouMame\PhpMonad\Option\Some;
8+
9+
/**
10+
* @template T
11+
* @implements Monad<T>
12+
*/
13+
abstract class Option implements Monad
14+
{
15+
/**
16+
* @template TValue
17+
* @param TValue $value
18+
* @return Option<TValue>
19+
*/
20+
public static function unit(mixed $value): self
21+
{
22+
return new Some($value);
23+
}
24+
}

src/Option/None.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EndouMame\PhpMonad\Option;
6+
7+
use Closure;
8+
use EndouMame\PhpMonad\Option;
9+
use Override;
10+
11+
/**
12+
* @template T
13+
* @extends Option<T>
14+
*/
15+
final class None extends Option
16+
{
17+
/**
18+
* @param T $value
19+
*/
20+
public function __construct(protected mixed $value)
21+
{
22+
}
23+
24+
/**
25+
* @template T2
26+
* @param Closure(T): static<T2> $f
27+
* @return static<T2>
28+
*/
29+
#[Override]
30+
public function bind(Closure $f): self
31+
{
32+
/** @var T2 */
33+
$v = null;
34+
35+
return self::unit($v);
36+
}
37+
38+
/**
39+
* @template TValue
40+
* @param TValue $value
41+
* @return None<TValue>
42+
*/
43+
#[Override]
44+
public static function unit(mixed $value): self
45+
{
46+
return new self($value);
47+
}
48+
}

src/Option/Some.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EndouMame\PhpMonad\Option;
6+
7+
use Closure;
8+
use EndouMame\PhpMonad\Option;
9+
use Override;
10+
11+
/**
12+
* @template T
13+
* @extends Option<T>
14+
*/
15+
final class Some extends Option
16+
{
17+
/**
18+
* @param T $value
19+
*/
20+
public function __construct(protected mixed $value)
21+
{
22+
}
23+
24+
/**
25+
* @param Closure(T): static<T> $f
26+
* @return static<T>
27+
*/
28+
#[Override]
29+
public function bind(Closure $f): self
30+
{
31+
return $f($this->value);
32+
}
33+
}

0 commit comments

Comments
 (0)