Sumant Tambe (17) [Avatar] Offline
#1
In section 13.4 of the book, there's discussing regarding seamless interchangeability of different monads. I'm not a fan of some of the claims/suggestions. I would like to discuss them. I'm happy to stand corrected. Here's my point of view.

Consider, page 311, second para, ... all monadic structures are alike and that we can freely switch between different monads. I believe, the intention here is to say that they share some commonalities as in they all support transform and mbind but not much further right? Unless one is talking two list monads (lazy and eager), there's isn't a significant overlap.

Also, page 313, second para ...just change the definitions of transform and filter... In this case the suggestion is to reimplement transform and filter for collections if one wants to implement tests for production reactive streams pipelines. In practice, people might use something like RxCPP or something equally sophisticated to implement reactive streams. It might be std::future with .then chaining. As these are specialized monads, there are api functions that would make sense only in them. For example, Consider operators in Rx combine_latest, debounce, subscribe_on, produce_on, delay, timeout. They don’t appear to have an obvious replacement in other monads. Even changing from Future to Rx might be very hard because these monads are semantically quite different. How would one go about testing a pipeline that has used these operators?

I’ll try to answer my own question here. I think it might work out to some extent in case of reactive streams and collections because they are duals of each other. That’s a theoretical argument. In practice, one would drive the reactive streams directly in a test by using Subjects from Rx (instead of really waiting for input from network) From the book it would be a replacement of boost.asio.server with a predefined array of input data. However, in general, it is probably harder than it looks for the rest of the pipeline because of api differences.

Rewriting large swaths of operators for two or more monads would be a deterrent. I'm not claiming any solution.

What do you think?
Ivan Cukic (97) [Avatar] Offline
#2
> For example, Consider operators in Rx combine_latest, debounce, subscribe_on, produce_on, delay, timeout.

They are not monadic operations. So, other monads don't need to have equivalents.

But, it should be still easy to test in the same manner - instead of using vector<T>, we would have (for example) vector<with_time<T>> for which debounce and similar could be implemented.

I've added some clarification:
   829 In this section,                                                                
   830 we are going to leverage the fact that all monadic structures are alike         
~  831  --                                                                             
+  832 they all have `mbind`, `transform` and `join` defined on them                   
+  833  --                                                                             
+  834 and that if we base our logic on these functions                                
+  835 (or functions built on top of these),                                           
+  836 we can freely switch between different monads                                   
   837 without changing the main program logic                                         
   838 so that we can implement tests for our program.