-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP feat: add monadic support #74
Conversation
921bf78
to
9c7ba93
Compare
9c7ba93
to
647f21f
Compare
Thanks! I did not forget about this PR. I'll review it when I have time, probably this weekend. |
No worries. :-) My thoughts on the PR: Perhaps it would be more interesting to split At least, I believe it would simplify my usage of the library :-) |
I looked at this today. To be frank I'm reluctant to follow this path because it'd result in duplication of almost the entire API.
But this is still possible even with the current code, right? You just need to perform all your effects before you start rendering. This way you can prepare all necessary information (e.g. fetch something via HTTP) and then use via the extension mechanism. The only use I can see for introducing a monad is for manipulation of a state during rendering, e.g. if you want to assign an integer per link.
It looks like the trans/render extension-constructors could allow the user to inspect inlines constructed so far (right now we only show the original inlines inside the |
I agree with your vision for simplicity, and that is completely in line with the package philosophy. Just for completeness, here was my goal. For my (very specific) use case of rendering some specific blocks using external services, the usage just seemed weird.
I can't just use the
This solution doesn't work as scanning only sees the original blocks. And I wanted to keep extensions A and B separate for modularity and reusability. One of the points of this PR was to know if there was another way, preserving composition and reasonability. Monads would allow for a single pass, but agreed, in exchange for complexity and heavy API modifications. I concur that the PR may not be the best idea :-) But I don't know if bad interactions are possible this way, so long as they only see the currently transformed structure (just as with function composition?). Extensions would still be testable independently. And in some cases (such as here), interactions might just be what we are looking for. In all cases, I believe the user may be able to decide using the order of the extensions? I also have to admit that this is clearly not the everyday use case. For those type of cases and to keep the API simple, wouldn't it be possible to keep the existing API as is (not introducing a constructor to access the tranformed content), but have and expose an intermediate data structure for The process could be:
The upside is that the client is free to do whatever it wants with the structure before rendering, including side-effects. Or it can also use the existing API, preserving performance. |
I'm going to close this since there hasn't been much activity on this PR for a while. I've just merged #116 which hopefully will make implementing custom renders posible. |
This PR would add support for monadic transformation and rendering.
The main motivation is to give the possibility for transforming and rendering in a certain monad (as requested in #46 ). For example, one might want to call an external service to render a specific content.
The scan alternative (i.e. doing a scanning beforehand, then send the results to the rendering extension) is not enough as scanning only consider the original content, not the one that might get constructed from the content and the application of other extensions. Adding the possibility to scan over the transformed content would solve that problem, but leave something to be desired (intermediate information generated, having some internals hidden but the transformed content publicly visible...).
This PR would solve the problem by introducing monad support for MMark, support that is already present in Lucid.
While the code should not introduce major breaking changes, there's still some open question regarding performance and ease of use (
MMarkM m
might seem a little weird, just as theparse
function that just doesn't care about the monad).Is this PR worth investigating?