@@ -84,13 +84,59 @@ public function and(self ...$operands): self
8484 return self ::create (min ($ operandValues ));
8585 }
8686
87+ /**
88+ * @template T
89+ * @param T[] $objects
90+ * @param callable(T): self $callback
91+ */
92+ public function lazyAnd (
93+ array $ objects ,
94+ callable $ callback ,
95+ ): self
96+ {
97+ $ results = [];
98+ foreach ($ objects as $ object ) {
99+ $ result = $ callback ($ object );
100+ if ($ result ->no ()) {
101+ return $ result ;
102+ }
103+
104+ $ results [] = $ result ;
105+ }
106+
107+ return $ this ->and (...$ results );
108+ }
109+
87110 public function or (self ...$ operands ): self
88111 {
89112 $ operandValues = array_column ($ operands , 'value ' );
90113 $ operandValues [] = $ this ->value ;
91114 return self ::create (max ($ operandValues ));
92115 }
93116
117+ /**
118+ * @template T
119+ * @param T[] $objects
120+ * @param callable(T): self $callback
121+ */
122+ public function lazyOr (
123+ array $ objects ,
124+ callable $ callback ,
125+ ): self
126+ {
127+ $ results = [];
128+ foreach ($ objects as $ object ) {
129+ $ result = $ callback ($ object );
130+ if ($ result ->yes ()) {
131+ return $ result ;
132+ }
133+
134+ $ results [] = $ result ;
135+ }
136+
137+ return $ this ->or (...$ results );
138+ }
139+
94140 public static function extremeIdentity (self ...$ operands ): self
95141 {
96142 if ($ operands === []) {
@@ -102,6 +148,36 @@ public static function extremeIdentity(self ...$operands): self
102148 return self ::create ($ min === $ max ? $ min : self ::MAYBE );
103149 }
104150
151+ /**
152+ * @template T
153+ * @param T[] $objects
154+ * @param callable(T): self $callback
155+ */
156+ public static function lazyExtremeIdentity (
157+ array $ objects ,
158+ callable $ callback ,
159+ ): self
160+ {
161+ $ lastResult = null ;
162+ $ results = [];
163+ foreach ($ objects as $ object ) {
164+ $ result = $ callback ($ object );
165+ if ($ lastResult === null ) {
166+ $ lastResult = $ result ;
167+ $ results [] = $ result ;
168+ continue ;
169+ }
170+ if ($ lastResult ->equals ($ result )) {
171+ $ results [] = $ result ;
172+ continue ;
173+ }
174+
175+ return self ::createMaybe ();
176+ }
177+
178+ return self ::extremeIdentity (...$ results );
179+ }
180+
105181 public static function maxMin (self ...$ operands ): self
106182 {
107183 if ($ operands === []) {
@@ -111,6 +187,29 @@ public static function maxMin(self ...$operands): self
111187 return self ::create (max ($ operandValues ) > 0 ? 1 : min ($ operandValues ));
112188 }
113189
190+ /**
191+ * @template T
192+ * @param T[] $objects
193+ * @param callable(T): self $callback
194+ */
195+ public static function lazyMaxMin (
196+ array $ objects ,
197+ callable $ callback ,
198+ ): self
199+ {
200+ $ results = [];
201+ foreach ($ objects as $ object ) {
202+ $ result = $ callback ($ object );
203+ if ($ result ->yes ()) {
204+ return $ result ;
205+ }
206+
207+ $ results [] = $ result ;
208+ }
209+
210+ return self ::maxMin (...$ results );
211+ }
212+
114213 public function negate (): self
115214 {
116215 return self ::create (-$ this ->value );
0 commit comments