Skip to content

Instantly share code, notes, and snippets.

@fumieval
Created January 22, 2015 04:25
Show Gist options
  • Save fumieval/fda1d920229d1831b881 to your computer and use it in GitHub Desktop.
Save fumieval/fda1d920229d1831b881 to your computer and use it in GitHub Desktop.
objective pipes?
import Control.Object
import Control.Object.Mortal
data Claim a' a b' b where
UNeed :: Claim a' a b' b a'
UGive :: a -> Claim a' a b' b ()
DNeed :: Claim a' a b' b b
DGive :: b' -> Claim a' a b' b ()
type Proxy a' a b' b = Mortal (Claim a' a b' b)
type Pipe = Proxy () a () b
(>->) :: Monad m
=> Proxy a' a () b m r
-> Proxy () b c' c m r
-> Proxy a' a c' c m r
p >-> q = mortal $ \case
UGive a -> do
((), p') <- EitherT $ runMortal p (UGive a)
pass $ p' >-> q
UNeed -> do
(a', p') <- EitherT $ runMortal p UNeed
return (a', p' >-> q)
DGive c' -> do
((), q') <- EitherT $ runMortal q (DGive c')
return (a', p >-> q')
DNeed -> do
(c, q') <- EitherT $ runMortal q DNeed
return (c, p >-> q')
where
stream p q = do
(b, p') <- EitherT $ runMortal p DNeed
((), q') <- EitherT $ runMortal q (UGive b)
return (p', q')
pass :: Monad m -> a -> m ((), a)
pass a = return ((), a)
await :: Monad m => Pipe a x m a
await = mortal $ \case
UGive a -> left a
UNeed -> pass await
DGive _ -> pass await
DNeed -> pass await
yield :: Monad m => Pipe x a m ()
yield a = mortal $ \case
UGive _ -> pass (yield a)
UNeed -> pass (yield a)
DGive _ -> pass (yield a)
DNeed -> return (a, left ())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment