Open gusty opened 5 years ago
I think it would make sense to add some more documentation about MonadPlus
. Perhaps something like:
Monad plus is an additive monad. Use it when you expect one or more results. The name comes from Haskell. See computation-zoo for more information.
I've added a pull request where I've tried to fill in some of the information: #141
Any thoughts on this @cmeeren?
About what? the last update I can see in this issue is from almost 2 years ago.
I just wanted to add my two cents to this before closing #346.
I think that computation expressions should not deviate from universally understood concepts as that would surprise and confuse users (especially newbies such as myself). A try...with operation for instance should always handle exceptions and not propagate them (in other words it should behave similarly to the try...with expression outside of a computation expression). This is currently not the case for lazy monads but is the case for strict monads, and I'm hoping this discrepancy will be fixed by any future redesign.
This is currently not the case for lazy monads
Wait, what? Are you saying that if I replaced the built-in async
with monad
from FSharpPlus, the exception handling would be very different? That is indeed confusing (and yet another reason I'm sceptical of using the generic CEs from FSharpPlus).
Perhaps in order for a redesign to happen, we need to have some idea about how what kind of design should be suitable. Since v2 is coming up we have more room for breaking changes.
From what I hear it sounds like there would be value in having more strict builders in order to avoid confusion.
I think the issue is that try .. with has different requirements when the monad is lazy.
For a strict monad, we can use the generic try .. with which is already included and working in the monad.strict
(or simply monad'
) generic computation expression.
Lazy monads on the other hand can't use a generic try .. with and each type needs to provide a specific TryWith
implementation.
At the moment we have to educate the user to prevent him to write such code but ideally a workflow that is not lazy over a type that doesn't provide a TryWith
method should not compile and throw a compiler error stating that.
I'm not sure if that's achievable, maybe if we move the generic TryWith
from the Monad file to the strict builders and replace them with a compiler error message will address the issue, at the cost of removing the possibility of customizing the TryWith
for strict monads.
@nikolamilekic even withouth this library, try .. with is used in all common F# lazy monads, namely the built-in seq
and async
.
Actually, looking at the code, we already call a generic try with for strict builders. So, all we have to do is to fail at compile-time in the generic TryWith
See #347
I'm opening this issue as a centralized place to discuss and review the current design of the generic Computation Expressions.
The main issue of the current design was highlighted by @cmeeren recently and has to do with the "autosense" design decision, to allow to figure out automatically in many trivial cases the evaluation strategy of the Computation (lazy vs strict).
We can discuss to change it, make it more explicit, or add another set of builders that are more strict and keep backwards compatibility.
Please raise all your questions, opinions, proposals, here.