I\'m attempting to implement a simple web server with Haskell and the Pipes library. I understand now that cyclic or diamond topologies aren\'t possible wi
I was wrong when I originally said you could not handle diamond topologies. I later discovered a sensible way to do this using an ArrowChoice-like interface and included the solution in pipes-3.2.0 in the form of the leftD and rightD combinators. I'll explain how it works:
Instead of nesting proxy transformers, you wrap the result with a Left or Right
routeRequest ::
(Monad m, Proxy p)
=> () -> Pipe p HTTPRequest (Either HTTPRequest HTTPRequest) m r
routeRequest () = runIdentityP $ forever $ do
httpReq <- request ()
let method = getMethod httpReq
let (URI uri) = getURI httpReq
respond $ case method of
GET -> Left httpReq
POST -> Right httpReq
Then you can selectively apply each handler to each branch and then merge the branches:
routeRequest >-> leftD handleGET >-> rightD handlePOST >-> mapD (either id id)
:: (Monad m, Proxy p) => () -> Pipe p HTTPRequest ByteString IO r
If you have more than two branches then you will have to nest Eithers, but that is just a limitation of how ArrowChoice works.