Comment by louthy
2 days ago
In C# you can implement SelectMany for a type and that gives this:
from id in ParseId(inputId)
from user in FindUser(id)
from posts in FindPostsByUserId(id)
from res in DeactivateDecision(user, posts)
select res;
It is the equivalent to do-notation (was directly inspired by it). Here's an example from the language-ext Samples [1], it's a game of 21/pontoon.
> I wrote what you might call an acid test for monad implementations a while back: https://jerf.org/iri/post/2928/ It's phrased in terms of tutorials but it works for implementations as well; you should be able to transliterate the example into your monad implementation, and it ought to look at least halfway decent if it's going to be usable.
If I try to implement the test from your blog with Seq type in language-ext (using C#), then I get:
Seq<(int, string)> minimal(bool b) =>
from x in b ? Seq(1, 2) : Seq(3, 4)
from r in x % 2 == 0
? from y in Seq("a", "b")
select (x, y)
: from y in Seq("y", "z")
select (x, y)
select r;
It yields:
[(1, y), (1, z), (2, a), (2, b)]
[(3, y), (3, z), (4, a), (4, b)]
Which I think passes your test.
[1] https://github.com/louthy/language-ext/blob/main/Samples/Car...
It looks like it. My claim was not (and is not) that C# can't implement it, but that what is discussed in the post does not.
Fair enough :)
By the way, I happen to agree on the general point, in my blog teaching Monads in C# [1], I wrote this:
"I often see other language ecosystems trying to bring monads into their domain. But, without first-class support for monads (like do notation in Haskell or LINQ in C#), they are (in my humble opinion) too hard to use. LINQ is the killer feature that allows C# to be one of very few languages that can facilitate genuine pure functional programming."
So, yeah, regular fluent method chaining isn't really enough to make monads useful.
[1] https://paullouth.com/higher-kinds-in-csharp-with-language-e...