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

Simpler Monad Constructors #809

Open
FreeApophis opened this issue Jan 16, 2025 · 4 comments
Open

Simpler Monad Constructors #809

FreeApophis opened this issue Jan 16, 2025 · 4 comments

Comments

@FreeApophis
Copy link
Member

FreeApophis commented Jan 16, 2025

lang-ext has something like this

using static LanguageExt.Prelude;

Option<string> myOption = None;

Marc Seeman has one for Either: https://blog.ploeh.dk/2024/12/16/a-restaurant-sandwich/

Either<string, int> myEither = 1337.ToRight().WithLeft<string>()

We already have a simplified one as the Return function, but none for Left.

Consistency should be key here, probably needs some thinking what we exactly want.

Funcky.Functional would probably the Prelude Object for us, if we go that route.

@FreeApophis FreeApophis changed the title Simpler Monad Constructors: Simpler Monad Constructors Jan 16, 2025
@bash
Copy link
Member

bash commented Jan 16, 2025

I have thought about the None case before I think having a None property in Functional (our prelude ^^) would be very useful. Would we also want the Some constructor there? I know that Rust has Some in the prelude...

The either version looks really cool, I gotta experiment with that. Maybe it's possible to do it with a static function instead of an extension method instead for symmetry?

@FreeApophis
Copy link
Member Author

It's a discussion opener, I do not have strong opinions yet, except that I really want that None.

@bash
Copy link
Member

bash commented Jan 27, 2025

An alternative for Either would be to specify the empty side first. This has the benefit of supporting the use as method-group.

It can easily co-exist with the specify-value-first approach.

Either<string, int> a = Either.WithLeft<string>.Return(10);
Either<string, int> b = Either.Right(10).WithLeft<string>(); 

Either<int, string> c = Either.WithRight<string>.Return(10);
Either<int, string> d = Either.Left(10).WithRight<string>(); 

enumerable.Select(Either.WithRight<string>.Return);

public static class Either
{
	public static RightBuilder<TRight> Right<TRight>(TRight right) => ...;

    public static LeftBuilder<TLeft> Left<TLeft>(TLeft left) => ...;

    public static class WithLeft<TLeft>
        where TLeft : notnull
    {
        public static Either<TLeft, TRight> Return<TRight>(TRight right)
            where TRight : notnull
            => Either<TLeft, TRight>.Right(right);
    }

    public static class WithRight<TRight>
        where TRight : notnull
    {
        public static Either<TLeft, TRight> Return<TLeft>(TLeft left)
            where TLeft : notnull
            => Either<TLeft, TRight>.Left(left);
    }
}

@FreeApophis
Copy link
Member Author

FreeApophis commented Jan 30, 2025

Looks actually pretty good, what would we do with the old Return which works at the moment like this:

Either<string, int> either = Either<string>.Return(42);

I found an old user story: #760

I think if we go this way we can close the idea to use Option<int> value = []

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants