Live data from Hacker News

Monads in C# (Part 2): Result

alexyorke.github.io

11–20 of 75 posts

Re: Monads in C# (Part 2): Result

#11

I really dislike this pattern: try { id = int.Parse(inputId); } catch (Exception ex) when (ex is FormatException or OverflowException) { throw new InvalidOperationException("DeactivateUser failed at: parse id", ex); } Where all you're doing when you catch an exception is throwing it in a more generic way. You could just let the FormatException or OverflowException bubble up, so the parent can handle those differently…

The original exception is available[1] in the InnerException though, so upstream can handle those differently.

[1]: https://learn.microsoft.com/en-us/dotnet/api/system.invalido...

Re: Monads in C# (Part 2): Result

#12

I really dislike this pattern: try { id = int.Parse(inputId); } catch (Exception ex) when (ex is FormatException or OverflowException) { throw new InvalidOperationException("DeactivateUser failed at: parse id", ex); } Where all you're doing when you catch an exception is throwing it in a more generic way. You could just let the FormatException or OverflowException bubble up, so the parent can handle those differently…

The original exception is available[1] in the InnerException though, so upstream can handle those differently. [1]: https://learn.microsoft.com/en-us/dotnet/api/system.invalido...

Ok, "destroy" was too strong, "hide" would have been a better choice of words.

You've still made it harder to handle.

Re: Monads in C# (Part 2): Result

#13
Small OT but part of me dies when data types that respect some laws are just labeled monads.

Nobody calls an array a monad, even though an array admits a monad instance.

Option, Result, Array, Either, FunkyFoo, whatever you want are just data types.

They only become monads when combined with some functions (map, bind, apply, flatmap), and that combination of things respects a set of law.

But calling a data type alone a monad has done nothing but overcomplicate the whole matter for decades.

Re: Monads in C# (Part 2): Result

#14
post #5

Idk, to me that constant Result looks extremely ugly and unergonomic, even just to type. I understand that this is complicated topic and there were a lot of strong opinions even inside of Google about it, but god, I miss absl::StatusOr and ASSIGN_OR_RETURN. Yes, it won’t work without preprocessor magic (and that’s why this article goes through heavy functional stuff, otherwise it just cannot work in language like C#)…

> I miss absl::StatusOr

Sounds like you would rather have an `ErrorOr` than a `Result`.

Both are union types wrapped in a monadic construct.

Re: Monads in C# (Part 2): Result

#15

I really dislike this pattern: try { id = int.Parse(inputId); } catch (Exception ex) when (ex is FormatException or OverflowException) { throw new InvalidOperationException("DeactivateUser failed at: parse id", ex); } Where all you're doing when you catch an exception is throwing it in a more generic way. You could just let the FormatException or OverflowException bubble up, so the parent can handle those differently…

[deleted]

Re: Monads in C# (Part 2): Result

#16

I really dislike this pattern: try { id = int.Parse(inputId); } catch (Exception ex) when (ex is FormatException or OverflowException) { throw new InvalidOperationException("DeactivateUser failed at: parse id", ex); } Where all you're doing when you catch an exception is throwing it in a more generic way. You could just let the FormatException or OverflowException bubble up, so the parent can handle those differently…

This code path leaves entire classes of unhandled parse exceptions on the table. I have a hard time believing this could be intentional. The safest and most concise approach is to use int.TryParse on the inputId and throw if it returns false.

Re: Monads in C# (Part 2): Result

#17
post #16

I really dislike this pattern: try { id = int.Parse(inputId); } catch (Exception ex) when (ex is FormatException or OverflowException) { throw new InvalidOperationException("DeactivateUser failed at: parse id", ex); } Where all you're doing when you catch an exception is throwing it in a more generic way. You could just let the FormatException or OverflowException bubble up, so the parent can handle those differently…

This code path leaves entire classes of unhandled parse exceptions on the table. I have a hard time believing this could be intentional. The safest and most concise approach is to use int.TryParse on the inputId and throw if it returns false.

Does it? Int.Parse says it can only return those 2 exceptions or ArgumentNullException, but nulls have been handled already.

https://learn.microsoft.com/en-us/dotnet/api/system.int32.pa...

Re: Monads in C# (Part 2): Result

#18

Small OT but part of me dies when data types that respect some laws are just labeled monads. Nobody calls an array a monad, even though an array admits a monad instance. Option, Result, Array, Either, FunkyFoo, whatever you want are just data types. They only become monads when combined with some functions (map, bind, apply, flatmap), and that combination of things respects a set of law. But calling a data type alone…

Sure, but this article's Result implements Ok(), Map(), and Bind()

Re: Monads in C# (Part 2): Result

#20
post #5

Idk, to me that constant Result looks extremely ugly and unergonomic, even just to type. I understand that this is complicated topic and there were a lot of strong opinions even inside of Google about it, but god, I miss absl::StatusOr and ASSIGN_OR_RETURN. Yes, it won’t work without preprocessor magic (and that’s why this article goes through heavy functional stuff, otherwise it just cannot work in language like C#)…

[deleted]
Post reply on HN