{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE GADTs #-} module Control.Eff.Concurrent.Examples where import GHC.Stack import Control.Eff import Control.Eff.Lift import Control.Monad import Data.Dynamic import Control.Eff.Concurrent.MessagePassing import Control.Eff.Concurrent.GenServer import Control.Eff.Concurrent.Dispatcher data TestApi deriving Typeable data instance Api TestApi x where SayHello :: String -> Api TestApi ('Synchronous Bool) Shout :: String -> Api TestApi 'Asynchronous deriving (Typeable) deriving instance Show (Api TestApi x) runExample :: IO () runExample = runLift $ runProcesses $ dispatchMessages example example :: ( HasCallStack , HasProcesses r , Member MessagePassing r , Member Process r , SetMember Lift (Lift IO) r) => Eff r () example = do me <- self lift (putStrLn ("I am " ++ show me)) server <- asServer @TestApi <$> spawn testServerLoop lift (putStrLn ("Started server " ++ show server)) let go = do x <- lift (putStr ">>> " >> getLine) res <- call server (SayHello x) lift (putStrLn ("Result: " ++ show res)) case x of ('q':_) -> return () _ -> go go testServerLoop :: forall r. (HasCallStack, Member MessagePassing r, Member Process r, SetMember Lift (Lift IO) r) => Eff r () testServerLoop = forever $ serve_ $ ApiHandler handleCast handleCall where handleCast :: Api TestApi 'Asynchronous -> Eff r () handleCast (Shout x) = do me <- self lift (putStrLn (show me ++ " Shouting: " ++ x)) handleCall :: Api TestApi ('Synchronous x) -> (x -> Eff r Bool) -> Eff r () handleCall (SayHello x) reply = do me <- self lift (putStrLn (show me ++ " Got Hello: " ++ x)) void (reply (length x > 3))