logoalt Hacker News

louthylast Monday at 3:07 PM1 replyview on HN

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...


Replies

jerflast Monday at 3:31 PM

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.

show 1 reply