Skip to content

Commit 408fdcc

Browse files
committed
Merge branch 'develop'
* develop: specify next release add Either::attempt() add Maybe::attempt()
2 parents d960085 + 6fbbd8e commit 408fdcc

15 files changed

Lines changed: 255 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## 5.15.0 - 2025-05-17
4+
5+
### Added
6+
7+
- `Innmind\Immutable\Maybe::attempt()`
8+
- `Innmind\Immutable\Either::attempt()`
9+
310
## 5.14.4 - 2025-05-07
411

512
### Fixed

docs/structures/either.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,19 @@ Either::left('something')->maybe()->match(
186186
); // returns null
187187
```
188188

189+
## `->attempt()`
190+
191+
This returns an [`Attempt`](attempt.md) containing the right value, in case of a left value it returns an `Attempt` with the error provided by the callable inside.
192+
193+
```php
194+
Either::right('something')
195+
->attempt(static fn() => new \Exception)
196+
->unwrap(); // returns 'something'
197+
Either::left('something')
198+
->attempt(static fn(string $left) => new \Exception($left))
199+
->unwrap(); // throws new \Exception('something')
200+
```
201+
189202
## `->memoize()`
190203

191204
This method force to load the contained value into memory. This is only useful for a deferred `Either`, this will do nothing for other either as the value is already known.

docs/structures/maybe.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,19 @@ Maybe::nothing()
166166
); // return 'something'
167167
```
168168

169+
## `->either()`
170+
171+
This returns an [`Attempt`](attempt.md) containing the value as a result and the error is provided by the callable.
172+
173+
```php
174+
Maybe::just('something')
175+
->attempt(static fn() => new \Exception)
176+
->unwrap(); // returns 'something'
177+
Maybe::nothing()
178+
->attempt(static fn() => new \Exception)
179+
->unwrap(); // throws the exception
180+
```
181+
169182
## `->memoize()`
170183

171184
This method force to load the contained value into memory. This is only useful for a deferred `Maybe`, this will do nothing for other maybe as the value is already known.

proofs/either.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,80 @@ static function($assert, $value) {
2424
$assert->true($loaded);
2525
},
2626
);
27+
28+
yield proof(
29+
'Either->attempt()',
30+
given(
31+
Set\Type::any(),
32+
Set\Type::any(),
33+
),
34+
static function($assert, $right, $left) {
35+
$assert->same(
36+
$right,
37+
Either::right($right)
38+
->attempt(static fn() => new Exception)
39+
->unwrap(),
40+
);
41+
42+
$expected = new Exception;
43+
$assert->same(
44+
$expected,
45+
Either::left($left)
46+
->attempt(static function($value) use ($assert, $left, $expected) {
47+
$assert->same($left, $value);
48+
49+
return $expected;
50+
})
51+
->match(
52+
static fn() => null,
53+
static fn($error) => $error,
54+
),
55+
);
56+
},
57+
);
58+
59+
yield proof(
60+
'Either::defer()->attempt()',
61+
given(
62+
Set\Type::any(),
63+
Set\Type::any(),
64+
),
65+
static function($assert, $right, $left) {
66+
$loaded = false;
67+
$attempt = Either::defer(static function() use (&$loaded, $right) {
68+
$loaded = true;
69+
70+
return Either::right($right);
71+
})->attempt(static fn() => new Exception);
72+
73+
$assert->false($loaded);
74+
$assert->same(
75+
$right,
76+
$attempt->unwrap(),
77+
);
78+
$assert->true($loaded);
79+
80+
$expected = new Exception;
81+
$loaded = false;
82+
$attempt = Either::defer(static function() use (&$loaded, $left) {
83+
$loaded = true;
84+
85+
return Either::left($left);
86+
})->attempt(static function($value) use ($assert, $left, $expected) {
87+
$assert->same($left, $value);
88+
89+
return $expected;
90+
});
91+
92+
$assert->false($loaded);
93+
$assert->same(
94+
$expected,
95+
$attempt->match(
96+
static fn() => null,
97+
static fn($error) => $error,
98+
),
99+
);
100+
$assert->true($loaded);
101+
},
102+
);
27103
};

proofs/maybe.php

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,4 +63,66 @@ static function($assert, $value) {
6363
$assert->true($loaded);
6464
},
6565
);
66+
67+
yield proof(
68+
'Maybe->attempt()',
69+
given(Set\Type::any()),
70+
static function($assert, $value) {
71+
$assert->same(
72+
$value,
73+
Maybe::just($value)
74+
->attempt(static fn() => new Exception)
75+
->unwrap(),
76+
);
77+
78+
$expected = new Exception;
79+
$assert->same(
80+
$expected,
81+
Maybe::nothing()
82+
->attempt(static fn() => $expected)
83+
->match(
84+
static fn() => null,
85+
static fn($error) => $error,
86+
),
87+
);
88+
},
89+
);
90+
91+
yield proof(
92+
'Maybe::defer()->attempt()',
93+
given(Set\Type::any()),
94+
static function($assert, $value) {
95+
$loaded = false;
96+
$attempt = Maybe::defer(static function() use (&$loaded, $value) {
97+
$loaded = true;
98+
99+
return Maybe::just($value);
100+
})->attempt(static fn() => new Exception);
101+
102+
$assert->false($loaded);
103+
$assert->same(
104+
$value,
105+
$attempt->unwrap(),
106+
);
107+
$assert->true($loaded);
108+
109+
$expected = new Exception;
110+
$loaded = false;
111+
$attempt = Maybe::defer(static function() use (&$loaded) {
112+
$loaded = true;
113+
114+
return Maybe::nothing();
115+
})->attempt(static fn() => $expected);
116+
117+
$assert->false($loaded);
118+
$assert->same(
119+
$expected,
120+
$attempt->match(
121+
static fn() => null,
122+
static fn($error) => $error,
123+
),
124+
);
125+
$assert->true($loaded);
126+
},
127+
);
66128
};

src/Either.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ public function maybe(): Maybe
156156
return $this->either->maybe();
157157
}
158158

159+
/**
160+
* @param callable(L): \Throwable $error
161+
*
162+
* @return Attempt<R>
163+
*/
164+
public function attempt(callable $error): Attempt
165+
{
166+
return $this->either->attempt($error);
167+
}
168+
159169
/**
160170
* Force loading the value in memory (only useful for a deferred Either)
161171
*

src/Either/Defer.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Innmind\Immutable\{
77
Either,
88
Maybe,
9+
Attempt,
910
};
1011

1112
/**
@@ -84,6 +85,14 @@ public function maybe(): Maybe
8485
return Maybe::defer(static fn() => self::detonate($captured)->maybe());
8586
}
8687

88+
#[\Override]
89+
public function attempt(callable $error): Attempt
90+
{
91+
$captured = $this->capture();
92+
93+
return Attempt::defer(static fn() => self::detonate($captured)->attempt($error));
94+
}
95+
8796
/**
8897
* @return Either<L1, R1>
8998
*/

src/Either/Implementation.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Innmind\Immutable\{
77
Either,
88
Maybe,
9+
Attempt,
910
};
1011

1112
/**
@@ -79,6 +80,13 @@ public function filter(callable $predicate, callable $otherwise): self;
7980
*/
8081
public function maybe(): Maybe;
8182

83+
/**
84+
* @param callable(L): \Throwable $error
85+
*
86+
* @return Attempt<R>
87+
*/
88+
public function attempt(callable $error): Attempt;
89+
8290
/**
8391
* @return Either<L, R>
8492
*/

src/Either/Left.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Innmind\Immutable\{
77
Either,
88
Maybe,
9+
Attempt,
910
};
1011

1112
/**
@@ -81,6 +82,13 @@ public function maybe(): Maybe
8182
return Maybe::nothing();
8283
}
8384

85+
#[\Override]
86+
public function attempt(callable $error): Attempt
87+
{
88+
/** @psalm-suppress ImpureFunctionCall */
89+
return Attempt::error($error($this->value));
90+
}
91+
8492
/**
8593
* @return Either<L1, R1>
8694
*/

src/Either/Right.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use Innmind\Immutable\{
77
Either,
88
Maybe,
9+
Attempt,
910
};
1011

1112
/**
@@ -87,6 +88,12 @@ public function maybe(): Maybe
8788
return Maybe::just($this->value);
8889
}
8990

91+
#[\Override]
92+
public function attempt(callable $error): Attempt
93+
{
94+
return Attempt::result($this->value);
95+
}
96+
9097
/**
9198
* @return Either<L1, R1>
9299
*/

0 commit comments

Comments
 (0)