Skip to content

Instantly share code, notes, and snippets.

@sjoerdvisscher
Created January 16, 2012 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sjoerdvisscher/1621224 to your computer and use it in GitHub Desktop.
Save sjoerdvisscher/1621224 to your computer and use it in GitHub Desktop.
Pipe composition based on adjunctions.
import Control.Monad.Free
import Data.Functor.Coproduct
import Data.Functor.Adjunction
combine :: Adjunction f u => u a -> f b -> (a, b)
combine ua = rightAdjunct (\b -> fmap (\a -> (a, b)) ua)
type Pipe f u r = Free (Coproduct f u) r
compose :: (Functor g, Functor v, Adjunction f u) => Pipe g u r -> Pipe f v r -> Pipe g v r
compose (Free (Coproduct (Left gp))) p2 = Free (Coproduct (Left (fmap (`compose` p2) gp)))
compose p1 (Free (Coproduct (Right vp))) = Free (Coproduct (Right (fmap (p1 `compose`) vp)))
compose (Free (Coproduct (Right up))) (Free (Coproduct (Left fp))) = uncurry compose (combine up fp)
compose (Pure r) _ = Pure r
compose _ (Pure r) = Pure r
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment