-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathOption.php
102 lines (80 loc) · 2 KB
/
Option.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
<?php
/**
* Option is the base class for Some and None.
*
* Options are used to indicate the presence or absence of a value. Return values do not need to be explicitly checked since iterators are available. This is inspired by Scala's Option. Ideally this would be an abstract class but PHP doesn't let an abstract class implement an interface.
*/
class Option implements Iterator {
protected $v;
private $times = 0;
function __construct($v) {
$this->v = $v;
}
function current() {
return $this->v;
}
function key() {
return 0;
}
function next() {
$this->times++;
return ($this->times < 1);
}
function rewind() {
$this->times = 0;
}
function valid() {
return ($this->times < 1);
}
}
class Some extends Option {
public function map($f) {
$this->assertCallable($f);
return new Some($f($this->v));
}
public function flatMap($f) {
$this->assertCallable($f);
$ret = $f($this->v);
if (!($ret instanceof Option)) {
throw new Exception("$f must return an Option.");
}
return $ret;
}
public function get() {
return $this->v;
}
public function getOrElse($d) {
return $this->get();
}
private function assertCallable($f) {
if (!is_callable($f)) {
throw new Exception("$f is not callbable");
}
}
}
class None extends Option {
public function __construct() {
}
public function next() {
return false;
}
public function valid() {
return false;
}
public function map($f) {
return $this;
}
public function flatMap($f) {
return $this;
}
public function each($f) {
}
public function get() {
throw new Exception('No such element.');
}
public function getOrElse($d) {
return $d;
}
}
$None = new None();
?>