monad-schedule 0.1.0.0 → 0.1.1.0
raw patch · 7 files changed
+79/−14 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Monad.Schedule.Class: instance (GHC.Base.Functor m, Control.Monad.Schedule.Class.MonadSchedule m) => Control.Monad.Schedule.Class.MonadSchedule (Control.Monad.Trans.Identity.IdentityT m)
+ Control.Monad.Schedule.Class: instance Control.Monad.Schedule.Class.MonadSchedule Data.Functor.Identity.Identity
+ Control.Monad.Schedule.RoundRobin: type RoundRobin = RoundRobinT Identity
+ Control.Monad.Schedule.Sequence: type Sequence = SequenceT Identity
+ Control.Monad.Schedule.Trans: type Schedule diff = ScheduleT diff Identity
+ Control.Monad.Schedule.Yield: runYield :: Yield a -> a
+ Control.Monad.Schedule.Yield: runYieldIO :: MonadIO m => YieldT m a -> m a
+ Control.Monad.Schedule.Yield: runYieldT :: Monad m => YieldT m a -> m a
+ Control.Monad.Schedule.Yield: type Yield = YieldT Identity
+ Control.Monad.Schedule.Yield: type YieldT = ScheduleT ()
+ Control.Monad.Schedule.Yield: yield :: Monad m => YieldT m ()
Files
- CHANGELOG.md +9/−2
- monad-schedule.cabal +3/−2
- src/Control/Monad/Schedule/Class.hs +24/−10
- src/Control/Monad/Schedule/RoundRobin.hs +3/−0
- src/Control/Monad/Schedule/Sequence.hs +3/−0
- src/Control/Monad/Schedule/Trans.hs +3/−0
- src/Control/Monad/Schedule/Yield.hs +34/−0
CHANGELOG.md view
@@ -1,5 +1,12 @@ # Revision history for monad-schedule -## 0.1.0.0 -- YYYY-mm-dd+## 0.1.1.0 -- 2022-06-25 -* First version. Released on an unsuspecting world.+* Added Yield scheduling monad+* Added Identity instance++## 0.1.0.0 -- 2022-03-27++* Added MonadSchedule clas+* Added free scheduling transformer ScheduleT+* Added instances for common transformers
monad-schedule.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: monad-schedule-version: 0.1.0.0+version: 0.1.1.0 license: MIT license-file: LICENSE author: Manuel Bärenz@@ -20,10 +20,11 @@ library exposed-modules: Control.Monad.Schedule.Class+ Control.Monad.Schedule.OSThreadPool Control.Monad.Schedule.RoundRobin Control.Monad.Schedule.Sequence Control.Monad.Schedule.Trans- Control.Monad.Schedule.OSThreadPool+ Control.Monad.Schedule.Yield build-depends: base >= 4.13.0 && <= 4.17 , stm >= 2.5
src/Control/Monad/Schedule/Class.hs view
@@ -17,28 +17,30 @@ -- base import Control.Arrow import Control.Concurrent+import Control.Monad (void)+import Control.Monad.IO.Class import Data.Either import Data.Foldable (fold, forM_)-import Data.List.NonEmpty hiding (length) import Data.Function+import Data.Functor.Identity import Data.Kind (Type)+import Data.List.NonEmpty hiding (length)+import Data.Maybe (fromJust) import Data.Void+import Prelude hiding (map, zip)+import Unsafe.Coerce (unsafeCoerce) +import qualified Data.List.NonEmpty as NonEmpty+ -- transformers import Control.Monad.Trans.Accum import Control.Monad.Trans.Class-import Control.Monad.Trans.Writer-import Control.Monad.Trans.Reader-import qualified Data.List.NonEmpty as NonEmpty import Control.Monad.Trans.Cont-import Control.Monad (void)-import Unsafe.Coerce (unsafeCoerce)-import Data.Functor.Identity-import Data.Maybe (fromJust)-import Prelude hiding (map, zip)-import Control.Monad.IO.Class import Control.Monad.Trans.Except+import Control.Monad.Trans.Identity import Control.Monad.Trans.Maybe+import Control.Monad.Trans.Reader+import Control.Monad.Trans.Writer {- | 'Monad's in which actions can be scheduled concurrently. @@ -88,6 +90,10 @@ strength :: Functor m => (a, m b) -> m (a, b) strength (a, mb) = (a, ) <$> mb +-- | When there are no effects, return all values immediately+instance MonadSchedule Identity where+ schedule as = ( , []) <$> sequence as+ {- | Fork all actions concurrently in separate threads and wait for the first one to complete. @@ -118,6 +124,14 @@ -- TODO Needs dependency -- instance MonadSchedule STM where++-- | Pass through the scheduling functionality of the underlying monad+instance (Functor m, MonadSchedule m) => MonadSchedule (IdentityT m) where+ schedule+ = fmap runIdentityT+ >>> schedule+ >>> fmap (fmap (fmap IdentityT))+ >>> IdentityT -- | Write in the order of scheduling: -- The first actions to return write first.
src/Control/Monad/Schedule/RoundRobin.hs view
@@ -4,6 +4,7 @@ -- base import Control.Monad.IO.Class+import Data.Functor.Identity import qualified Data.List.NonEmpty as NonEmpty -- transformers@@ -23,3 +24,5 @@ -- | Execute only the first action, and leave the others for later, preserving the order. instance Monad m => MonadSchedule (RoundRobinT m) where schedule actions = ( , NonEmpty.tail actions) <$> fmap pure (NonEmpty.head actions)++type RoundRobin = RoundRobinT Identity
src/Control/Monad/Schedule/Sequence.hs view
@@ -5,6 +5,7 @@ -- base import Control.Arrow ((>>>)) import Control.Monad.IO.Class+import Data.Functor.Identity import qualified Data.List.NonEmpty as NonEmpty -- transformers@@ -24,3 +25,5 @@ -- Essentially, this is 'sequenceA'. instance Monad m => MonadSchedule (SequenceT m) where schedule = sequenceA >>> fmap (, [])++type Sequence = SequenceT Identity
src/Control/Monad/Schedule/Trans.hs view
@@ -17,6 +17,7 @@ import Control.Category ((>>>)) import Control.Monad (join) import Data.Functor.Classes+import Data.Functor.Identity import Data.List.NonEmpty as N -- transformers@@ -60,6 +61,8 @@ These delays don't have any semantics, it can be given to them with 'runScheduleT'. -} type ScheduleT diff = FreeT (Wait diff)++type Schedule diff = ScheduleT diff Identity -- | The side effect that waits for a specified amount. wait :: Monad m => diff -> ScheduleT diff m ()
+ src/Control/Monad/Schedule/Yield.hs view
@@ -0,0 +1,34 @@+module Control.Monad.Schedule.Yield where++-- base+import qualified Control.Concurrent as Concurrent+import Control.Monad.IO.Class+import Data.Functor.Identity (Identity (runIdentity))++-- monad-schedule+import Control.Monad.Schedule.Class+import Control.Monad.Schedule.Trans++-- * 'YieldT'++-- | A monad for scheduling with cooperative concurrency.+type YieldT = ScheduleT ()++type Yield = YieldT Identity++-- | Let another thread wake up.+yield :: Monad m => YieldT m ()+yield = wait ()++runYieldT :: Monad m => YieldT m a -> m a+runYieldT = runScheduleT $ const $ return ()++runYield :: Yield a -> a+runYield = runIdentity . runYieldT++-- | Run a 'YieldT' value in a 'MonadIO',+-- interpreting 'yield's as GHC concurrency yields.+runYieldIO+ :: MonadIO m+ => YieldT m a -> m a+runYieldIO = runScheduleT $ const $ liftIO Concurrent.yield