Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(option): add Option::proceed() method #433

Merged
merged 3 commits into from
Dec 29, 2023
Merged

Conversation

devnix
Copy link
Contributor

@devnix devnix commented Dec 11, 2023

This is another idea of implementing a match method that I had after learning more bits of Rust: https://doc.rust-lang.org/rust-by-example/std/option.html

WDYT?

@coveralls
Copy link

coveralls commented Dec 11, 2023

Pull Request Test Coverage Report for Build 7349487827

  • 3 of 3 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.001%) to 99.012%

Totals Coverage Status
Change from base Build 7330553583: 0.001%
Covered Lines: 4208
Relevant Lines: 4250

💛 - Coveralls

@veewee
Copy link
Collaborator

veewee commented Dec 12, 2023

Hello,

Thanks for the PR.

For Result, we have proceed, which acts similar to what you want to achieve here in option:

/**
* Unwrapping and transforming a result can be done by using the proceed method.
* The implementation will either run the `$on_success` or `$on_failure` callback.
* The callback will receive the result or Throwable as an argument,
* so that you can transform it to anything you want.
*
* @template Ts
*
* @param (Closure(T): Ts) $success
* @param (Closure(Throwable): Ts) $failure
*
* @return Ts
*/
public function proceed(Closure $success, Closure $failure): mixed;

I've mentioned something similar in the original PR:

https://github.com/azjezz/psl/pull/356/files#r912345716

The conclusion in there was this one:

The same thing can be achieved by using mapOrElse() in combination with unwrap().
For your example implementation, this would mean:

$try_division = static function (int $dividend, int $divisor) use ($checked_divisor): string {
    return $checked_divisor($dividend, $divisor)->mapOrElse(
        static fn ($value) => sprintf('%s / %s = %s', $dividend, $divisor, $value),
        static fn() => sprintf('%s / %s failed!', $dividend, $divisor),
    )->unwrap();
};

From my point of view, this seems sufficient in line with your implementation as well.

If you are OK with calling mapOrElse with a final unwrap() in your codebase, I assume we don't need this and can close this?

@devnix
Copy link
Contributor Author

devnix commented Dec 12, 2023

For sure this can be done in userland! I was just imagining a way to make some operations easier after learning Rust's match syntactic sugar. For sure it can be done instead with mapOrElse() and unwrap(), it's just that it's not immediately obvious 😄

We can close it if you already concluded that you don't want a function just for this

@veewee
Copy link
Collaborator

veewee commented Dec 12, 2023

I've given it some second thoughts and do agree that this shortcut is more than welcome. I've skimmed through some of my packages and I frequently see me using the combination of mapOrElse with unwrap. There is no alternative for this combination in rust, most likely because they have the match operator and the ? operator as shortcuts already.

But to keep things consistent throughout the codebase, I suggest to rename it to proceed. That way, it's similar to what we do in ResultInterface.

The signature should be:

    /*
     * @template Ts
     *
     * @param (Closure(T): Ts) $some
     * @param (Closure(): Ts) $none
     *
     * @return Ts
     */
    public function proceed(Closure $some, Closure $none): mixed;

That way, proceed will be used to map any possible scenario and unwind the result in one fixed type. That way, we can keep a consistent API throughout all these monad-like classes and interfaces.

The example will look like this:

$try_division = static function (int $dividend, int $divisor) use ($checked_divisor): string {
    return $checked_divisor($dividend, $divisor)->proceed(
        some: static fn ($value) => sprintf('%s / %s = %s', $dividend, $divisor, $value),
        none: static fn() => sprintf('%s / %s failed!', $dividend, $divisor),
    );
};

WDYT?

@devnix devnix changed the title feat(option): add Option::match() method feat(option): add Option::proceed() method Dec 17, 2023
@devnix
Copy link
Contributor Author

devnix commented Dec 17, 2023

I think this one is ready too! 😄

@devnix devnix requested a review from veewee December 25, 2023 12:30
@veewee
Copy link
Collaborator

veewee commented Dec 26, 2023

Looks good, can you resolve conflicts so that it can be merged,

@veewee veewee added Priority: Medium This issue may be useful, and needs some attention. Status: Accepted It's clear what the subject of the issue is about, and what the resolution should be. Type: Enhancement Most issues will probably ask for additions or changes. labels Dec 26, 2023
@devnix
Copy link
Contributor Author

devnix commented Dec 28, 2023

Ready to go @veewee!

@veewee veewee merged commit bbc9eba into azjezz:next Dec 29, 2023
14 checks passed
@veewee
Copy link
Collaborator

veewee commented Dec 29, 2023

Nice, thanks!

@devnix devnix deleted the option-match branch December 29, 2023 09:47
renovate bot referenced this pull request in ben-challis/sql-migrations Dec 29, 2023
[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [azjezz/psl](https://togithub.com/azjezz/psl) | `2.8.0` -> `2.9.0` |
[![age](https://developer.mend.io/api/mc/badges/age/packagist/azjezz%2fpsl/2.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/packagist/azjezz%2fpsl/2.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/packagist/azjezz%2fpsl/2.8.0/2.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/packagist/azjezz%2fpsl/2.8.0/2.9.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

> [!WARNING]
> Some dependencies could not be looked up. Check the Dependency
Dashboard for more information.

---

### Release Notes

<details>
<summary>azjezz/psl (azjezz/psl)</summary>

### [`v2.9.0`](https://togithub.com/azjezz/psl/releases/tag/2.9.0):
Lenalee - 2.9.0

[Compare Source](https://togithub.com/azjezz/psl/compare/2.8.0...2.9.0)

#### What's Changed

- Apply fixes for Psalm 5.17 by
[@&#8203;veewee](https://togithub.com/veewee) in
[https://github.com/azjezz/psl/pull/431](https://togithub.com/azjezz/psl/pull/431)
- feat(type): add class_string types
([#&#8203;432](https://togithub.com/azjezz/psl/issues/432)) by
[@&#8203;zerkms](https://togithub.com/zerkms) in
[https://github.com/azjezz/psl/pull/435](https://togithub.com/azjezz/psl/pull/435)
- feat(option): add `Option::zip()`, `Option::zipWith()` and
`Option::unzip()` methods by
[@&#8203;devnix](https://togithub.com/devnix) in
[https://github.com/azjezz/psl/pull/434](https://togithub.com/azjezz/psl/pull/434)
- feat(option): add `Option::proceed()` method by
[@&#8203;devnix](https://togithub.com/devnix) in
[https://github.com/azjezz/psl/pull/433](https://togithub.com/azjezz/psl/pull/433)
- feat(option): new `Option::apply()` method by
[@&#8203;devnix](https://togithub.com/devnix) in
[https://github.com/azjezz/psl/pull/426](https://togithub.com/azjezz/psl/pull/426)

#### New Contributors

- [@&#8203;zerkms](https://togithub.com/zerkms) made their first
contribution in
[https://github.com/azjezz/psl/pull/435](https://togithub.com/azjezz/psl/pull/435)

**Full Changelog**: azjezz/psl@2.8.0...2.9.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/ben-challis/sql-migrations).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4xMDMuMSIsInVwZGF0ZWRJblZlciI6IjM3LjEwMy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiJ9-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: Medium This issue may be useful, and needs some attention. Status: Accepted It's clear what the subject of the issue is about, and what the resolution should be. Type: Enhancement Most issues will probably ask for additions or changes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants