4 ms·
This is all very basic, instead you can use C#'s new static interface methods feature to create higher-kinded traits where you can properly generalise over a mo
by louthy 10mo ago
This is all very basic, instead you can use C#'s new static interface methods feature to create higher-kinded traits where you can properly generalise over a monad trait (or applicatives, functors, foldables, etc.), which is what I do in language-ext [0].
I'm not saying that implementing SelectMany for specific data-types isn't valuable. It certainly ends up with more elegant and maintainable code, but the true power of monads and other pure-FP patterns opens up when you can fully generalise.
* I have a blog series on it that covers implementing Semigroups, Monoids, Functors, Foldables, Traversables, Applicatives, Monads, and Monad Transformers (in C#) [1]
* The monad episode (my 'Yet Another Monad Tutorial') [2]
* An entire app generalised over any monad where the monad must support specific traits [3]. It's the program I use to send out the newsletters from my blog.
Happy to answer any questions on it.
[0] https://github.com/louthy/language-ext/ https://github.com/louthy/language-ext/
[1] https://paullouth.com/higher-kinds-in-c-with-language-ext/ https://paullouth.com/higher-kinds-in-c-with-language-ext/
[2] https://paullouth.com/higher-kinds-in-csharp-with-language-ext-part-7-monads/ https://paullouth.com/higher-kinds-in-csharp-with-language-e...
[3] https://github.com/louthy/language-ext/tree/main/Samples/Newsletter/Newsletter https://github.com/louthy/language-ext/tree/main/Samples/New...
- FrustratedMonky 10mo agoSerious question, at this point, have all F# features been fully incorporated into C#?
- louthy 10mo agoNot discriminated unions, but they're coming (I think next version of C#). Although for now you can simulate them quite easily: public abstract record Either<L, R>; public sealed record Left<L, R>(L Value) : Either<L, R>; public sealed record Right<L, R>(R Value) : Either<L, R>; Pattern-matching works well with these simulated algebraic data-types. Obviously, exhaustiveness checks can't work on 'open' types, so it's not perfect, but you can unpack values, apply predicate clauses, etc. Other more niche features like type-providers don't exist either (although arguably those could be done with source-generators in C#). It's been a long time since I did any F#, so not sure if there's anything new in there I'm unaware of.
- debugnik 10mo agoThat will allocate for any constructed Either though. F#'s Result and ValueOption are value-types (structs), and value-type variants recently added support for sharing fields between variants when the name and type match.
- louthy 10mo agoYes, that's the limitation until the value-type DUs arrive in C# 15. In previous versions of language-ext, I defined Either as a struct with bespoke Match methods to pattern-match. But once pattern-matching appeared in C# proper, it didn't make sense to keep the struct type.
- FrustratedMonky 10mo agoSounds like C# 15 will be it then? Everything unique about F# will be incorporated. I guess a lot of how F# structures projects, like file order, or not using nulls, can be done by programming rigor?
- debugnik 9mo agoAren't the upcoming C# "value-type" DUs just a wrapper over an object reference? Value-type cases will be boxed AFAIK.