tag:blogger.com,1999:blog-15136575.post4919288366249501925..comments2023-10-17T12:00:16.772+01:00Comments on Code rant: Monads in C#-4. Linq loves Monads!Mike Hadlowhttp://www.blogger.com/profile/16441901713967254504noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-15136575.post-16563501951400712102017-05-08T05:08:50.149+01:002017-05-08T05:08:50.149+01:00Deeply helpful series, thank you. Could you provid...Deeply helpful series, thank you. Could you provide any more info on the fact that Linq works with Whatever, not just IEnumerable? Obviously, you are right and it does, as your code helpfully demonstrates!DWrighthttps://www.blogger.com/profile/05746226329644412303noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-53014076261728044562016-09-13T09:55:37.222+01:002016-09-13T09:55:37.222+01:00LINQ loves monads, but it's not the only langu...LINQ loves monads, but it's not the only language construct that loves monads - there is also another, which maybe loves them even more:<br /><br />"There is actually one more way for writing some monadic computations in C# using the recently added query syntax. The syntax is very limited compared to the encoding using iterators, but may be suitable for some computations." [Thomas Petricek, Encoding monadic computations in C# using iterators]<br /><br />Iterators are older than LINQ, but now we have of course async/await. We can "await anything" already:<br /> public IEnumerable Numbers()<br /> {<br /> return EnumeratorMonad.Build(async Yield =><br /> {<br /> await Yield(11);<br /> await Yield(22);<br /> await Yield(33);<br /> });<br /> }<br />(full source code is available on StackOverflow)<br /><br />But in C#7 arbitrary async return types are going to be possible, which would allow constructs like this:<br /><br />"Running this C# code:<br /><br />static void Main()<br />{<br /> var nullable = DoNullableThings();<br /> Console.WriteLine(nullable.HasValue);<br /> Console.ReadLine();<br />}<br /><br />static async NullableTaskLike DoNullableThings()<br />{<br /> var val1 = await GetValue();<br /> var val2 = await GetNoValue();<br /><br /> var val3 = await GetValue();<br /> var val4 = await GetValue();<br /> var val5 = await GetValue();<br /> var val6 = await GetValue();<br /> var val7 = await GetValue();<br /> return val7;<br />}<br /><br />static async NullableTaskLike GetValue()<br />{<br /> Console.WriteLine("Returning 1");<br /> return 1;<br />}<br /><br />static async NullableTaskLike GetNoValue()<br />{<br /> Console.WriteLine("Returning none");<br /> return await new NullableTaskLike();<br />}<br /><br />produces this output:<br /><br />Returning 1<br />Returning none<br />False<br /><br />(...) Using this, we can leverage the compiler to write code that acts like do-notation in Haskell. This implementation of Nullable is akin to Haskell's Maybe type."<br /><br />Source: "Quick and dirty monadic Nullable implementation for the C# Tasklike language proposal" on GitHubuser1https://www.blogger.com/profile/13561134680556205808noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-66970532137899967492011-01-15T13:33:59.575+00:002011-01-15T13:33:59.575+00:00Hi Yoann,
Thanks for asking the question again he...Hi Yoann,<br /><br />Thanks for asking the question again here.<br /><br />I've found Monads a difficult abstraction to think intuitively about, and until you have that intuitive understanding, it's always going to be hard to spot a situation where they are going to be useful. But with that insight, all kinds of situations appear. I've noticed that in the Haskell community, almost everything seems to end up as a Monad, and they often stack Monads to make new ones. So for the example of the community that's been playing with Monads for longest there is ample evidence that they have a wide range of applications.<br /><br />But anyway, I'm not answering your question. One example would be where you repeat a control structure frequently in your code. The simple Maybe Monad shows how you can work with 'nullable' types, wrapping up all the actual null checking. The Maybe Monad also shows how they can work as a 'short-circuit', allowing you to break out of a series of operations if a certain condition appears. That's an awkward thing to code imperatively. Monads can also be used to pass on state orthogonally to the domain logic of your program, a good example of this would be a Monadic Parser. CPS style code can also be nicely wrapped with a Monad, the F# Async Monad is an excellent example of this. The list goes on.<br /><br />I'm still at the foothills of understanding these functional abstractions myself, but I've found that looking at existing examples is a very good way of getting some insight. I plan to examine a number of different Monads here, starting with the Maybe Monad in the next couple of days, so hopefully that will help too.Mike Hadlowhttps://www.blogger.com/profile/16441901713967254504noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-37759397542048800862011-01-15T12:52:23.134+00:002011-01-15T12:52:23.134+00:00Hi Mike,
I left you a note on twitter yesterday r...Hi Mike,<br /><br />I left you a note on twitter yesterday regarding monads and my ineptitude to understand the benefits. <br /><br />First, these are great posts (and the ones before too).<br /><br />I can understand the implementation of monads and how they would work. however what I am not seeing is in which situations would you implement your own? <br /><br />Regards,<br /><br />Yoann.Yoann Esnaudhttps://www.blogger.com/profile/10288208834626071239noreply@blogger.comtag:blogger.com,1999:blog-15136575.post-72751299765219376172011-01-13T22:59:48.850+00:002011-01-13T22:59:48.850+00:00This blog series is shaping up to be something spe...This blog series is shaping up to be something special, good work.fschwietnoreply@blogger.com