Display warning for while loops inside lazy computation expressions for non-lazy types #364
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
With this PR we'll attempt to do as much as possible to help non-expert CE users to use generic CEs the right way.
To recap:
monad
is lazy.So, regarding the advanced constructs:
Now while-loops are the trickiest ones, because as opposed to for-loops the body is directly an expression, not a function, so when used within a strict type but in a lazy CE which has the wrong delay signature, the body of the while will be evaluated eagerly when passed as a parameter to the While method, so no chance to the auto-sense stuff, not even to throw a nice run-time error.
Also, as opposed to try-blocks, the while method is not compulsory, actually is not customizable so far.
So, no chance to do run-time or compile-time checks here.
The proposed solution
In this PR, we will introduce a compile-time check inside the While function that checks whether the type has a
TryWith
static method, that would be our way to "guess" if it's a lazy monad or not. If it fails it will display a compile-time warning.Here's the trickiest part: I think this should be good enough as all lazy monads implemented here have a corresponding
TryWith
implementation, so if you get the warning using one of those types, it is really the case of misusing the CE.But, it could be the rare case, that a user defined its own lazy monad without a
TryWith
because he's not planning to use try blocks, note thatTryWith
is normally unrelated to while loops.In this case the warning will display as well, but in this case we're talking about an advanced user, so he should be able to implement a basic
TryWith
just to get rid of the warning, or simply use a #nowarn "10710" directive.Conclusion: with this PR we're leaning on the safe side of the story and it will complete the picture of no surprising non CE expert users of the library, on the other hand there is a small chance that it will generate a warning on a very specific situation an advanced user can eventually run into and force him to either ignore it or implement a
TryWith
.