Use Monadic composition to simplify the implementation of DispatchMatchers#127
Merged
soareschen merged 18 commits intomainfrom Jul 15, 2025
Merged
Use Monadic composition to simplify the implementation of DispatchMatchers#127soareschen merged 18 commits intomainfrom
DispatchMatchers#127soareschen merged 18 commits intomainfrom
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Summary
This PR introduces basic monadic composition support through the
cgp-monadcrate. The crate offers thePipeMonadichandler, which performs monadic composition(>>)over theComputer,TryComputer, andHandlercomponents.The
PipeMonadichandler has limited support for monadic composition over a "simple" monadic types, e.g.Resultor identity. The monad cannot support generic types, e.g.impl Future<Output=T>, due to Rust not yet supporting impl trait in type aliases (TAIT) rust-lang/rust#63063.Similarly, monad transformers are not supported, due to the difficulty in threading monadic
Futures in the continuation, while still satisfying the lifetime andSendbounds. While it is possible to implement monad transformers excluding support for futures, they are not useful for CGP, due to us needing to support async continuations for theHandlertrait.This means that for now, if you want to compose two monads, you have to manually implement a brand new monad that is a composition of the two. But hopefully this need will be rare, due to Rust already offer compelling alternatives for most of the use cases of monad transformers, such as reader, state, and result.
The main use case of implementing
PipeMonadicis to support the use of theResultmonad withinDispatchMatchers. With this, the implementation ofDispatchMatchersbecomes simply monadic composition overResult.In the future, this form of monadic composition will also be useful for non-deterministic computation, such as to support property-based testing.
Implementation Details
The monadic implementation in CGP is not exactly the
Monadinstance we typically know in Haskell. Instead, each "monadic provider" implements the monadic composition(>>)to compose two providers that implementComputer,TryComputer, andHandler. Essentially, this works similar to monad transformers over identity (Computer),Result(TryComputer), and async + result (Handler).We mainly choose this approach, as described earlier, because of the existing challenges in representing an unboxed
impl Futureas a monad. Once TAIT is stabilized in the future, we can revisit the design again, and hopefully able to implement generalized monads in CGP.