Haskell Pipes and Branching

依然范特西╮ 提交于 2019-11-30 12:45:05

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.

I have not run your code, but I think I spotted a problem.

routeRequest'' = runProxyK $ routeRequest''' <-< unitU

routeRequest''' is requesting data from unitU which has nothing to supply, so it hangs.

:t runProxy $ unitU >-> printD

Will type check but nothing runs.

It seems like the data is being sent to the wrong level of the monad transformer, data which is flowing into routeRequest should be flowing into routeRequest'''. The data flowing into the wrong level of the monad transformer is what is probably causing you to need to leave of the type signature to get everything to type check. With the type signature routeRequest is expecting a () coming from upstream and, I bet, with no type signature it is allowed to be polymorphic.

In your definition of routeRequest you could "close the pipe", I think that is what it is called, by using unitD which would disallow your construction even when routeRequest''' does not have the type signature.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!