question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

More compostional or fluent handling of Eithers with varied Right Results

See original GitHub issue

Simple commented code:

       public static Either<string, string> GetTestMessageType(JObject msg)
        {
            // after some lookup/validation msg, suppose return as:
            return Right("GET_AUTHORS");
        }

        public static Either<string ,Func<JObject, MessageResult>> GetTestHandler(string key)
        {
            try
            {
                // Handlers Dictonary lookup sucsess
                return Right(Handlers.Get(key));
            }
            catch (Exception e)
            {
                // Handlers Dictonary lookup failed
                return Left($"Handler {key} not found. ({e.Message})");
            }
        }

        public static string TestMessageResultError(string err)
        {
            return $"Error:{err}";
        }

        public static object HandleTestMessage(JObject msg)
        {

            // Valid message type? 
            var x = GetTestMessageType(msg);

            // if not return error
            if (x.IsLeft)
            {
                return TestMessageResultError(x.Match(Left: l => l, Right: _ => ""));
            }

            // extract Message Type
            var mt = x.Match(Left: l => l, Right: r => r);

            // Handler exist? 
            var h = GetTestHandler(mt);

            // if not Return error Message Type cannot be handled
            if (h.IsLeft)
                return TestMessageResultError(h.Match(Left: l => l, Right: _ => ""));

            // extract handler func
            var f = h.Match(Left: l => null, Right: r => r);

            // Execute Handler func with msg
            return f(msg);

        }

GetTestMessageType and GetTestHandler return Either with varied Right results.

HandleTestMessage uses both to for handling msg but in verbose manner.

Any suggestion to make it more compostional or fluent style?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:13 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
louthycommented, Apr 30, 2018

Just to be clear, this is a limitation of C#. When you use the ternary operator:

   a = b ? c : d;

If there isn’t a common base type shared by c and d then C# will claim it can’t infer the type of the expression. Even if the type of a is known.

  • The return type for Right<R>(r) is EitherRight<R>
  • The return type for Left<L> is EitherLeft<L>(l).

They don’t share the same base type

And therefore C# can’t work out what’s going on. So, you can’t do this:

    var a = b 
        ? Right<R>(r) 
        : Left<L>(l);
  • The return type for Right<L, R>(r) is Either<L, R>
  • The return type for Left<L, R>(l) is Either<L, R>.

Which clearly share the same return type (note both L and R are provided for both), and so you can call:

    var a = b 
        ? Right<L, R>(r) 
        : Left<L, R>(l);

Now the Bind function that can be called on EitherLeft<L> or EitherRight<R> is there to provide the other type in the Either

So,

  • For EitherLeft<L> the Bind operation provides the R type.
  • For EitherRight<R> the Bind operation provides the L type.

So, there are 3 ways you can do this. And the one you chose should probably be based on the resulting attractiveness/readability of the code:

    static Either<string, Func<JObject, MessageResult>> GetTestHandler(string type) =>
        type == "GET_AUTHORS"
            ? Right(HandleGetAuthors)
            : Left($"Invalid Message type {type}").Bind<Func<JObject, MessageResult>>();

    static Either<string, Func<JObject, MessageResult>> GetTestHandler(string type) =>
        type == "GET_AUTHORS"
            ? Right(HandleGetAuthors).Bind<string>()
            : Left($"Invalid Message type {type}");

    static Either<string, Func<JObject, MessageResult>> GetTestHandler(string type) =>
        type == "GET_AUTHORS"
            ? Right<string, Func<JObject, MessageResult>>(HandleGetAuthors)
            : Left<string, Func<JObject, MessageResult>>($"Invalid Message type {type}");
0reactions
imranypatelcommented, Apr 26, 2018

@bender2k14 Thank you.

Just for completeness and documentation for beginners like myself, based on your response, here is the revised version in expression style:

    static Either<string, Func<JObject, MessageResult>> GetTestHandler(string type) =>
            (type == "GET_AUTHORS")
            ? Right(HandleGetAuthors)
            : Left($"Invalid Message type {type}").Bind<Func<JObject, MessageResult>>()
Read more comments on GitHub >

github_iconTop Results From Across the Web

Ethers
Handling and control of exposure​​ Diethyl ether (ethyl ether, ether) must be handled in the laboratory using only best practice methodology, ...
Read more >
A numerical investigation of the performance ...
The aim of the current study is to investigate the effects of the stoichiometry of oxymethylene ether on the in-cylinder combustion behaviour ...
Read more >
Numerical modeling of diesel and polyoxymethylene ...
Oxymethylene ethers have a 40–50% lower heating value than diesel due to the high oxygen content. Conversely, more OME fuel needs to be ......
Read more >
18.2: Preparing Ethers
Acid-catalyzed dehydration of small 1º-alcohols constitutes a specialized industrial method of preparing symmetrical ethers. This reaction ...
Read more >
STAAR English I Expository Scoring Guide April 2021
Write an essay explaining how receiving support from others can help you achieve success. Be sure to —. ○ clearly state your thesis....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found