module Broker where import Cleff import Control.Concurrent (forkIO, threadDelay) import Control.Monad (void) nestedImpl :: Int -> (String -> (Bool -> IO ()) -> IO ()) -> IO () nestedImpl i cb = void . forkIO $ do threadDelay $ 1 * 1000 * 1000 cb (show i) \b -> putStrLn $ "result " ++ show b data Broker :: Effect where Subscribe :: Int -> (String -> m Bool) -> Broker m () subscribe :: Broker :> es => Int -> (String -> Eff es Bool) -> Eff es () subscribe channel = send . Subscribe channel runBroker :: IOE :> es => Eff (Broker : es) a -> Eff es a runBroker = interpret \case Subscribe channel cb -> withToIO \toIO -> do putStrLn $ "Subscribe: " ++ show channel nestedImpl channel \s icb -> icb =<< toIO (cb s) prog :: (IOE :> es, Broker :> es) => Eff es () prog = do subscribe 1 \_ -> pure True subscribe 2 \_ -> pure False liftIO $ threadDelay $ 3 * 1000 * 1000 runProg :: IO () runProg = runIOE $ runBroker prog