Haskell Pipes and Branching

后端 未结 2 1050
轮回少年
轮回少年 2021-01-02 05:51

Problem

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

2条回答
  •  旧巷少年郎
    2021-01-02 06:19

    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.

提交回复
热议问题