motor 0.1.0.0 → 0.1.1.0
raw patch · 6 files changed
+34/−20 lines, 6 filesdep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base
API changes (from Hackage documentation)
+ Motor.FSM: call :: MonadFSM m => m Empty Empty a -> m r r a
+ Motor.FSM.Class: call :: MonadFSM m => m Empty Empty a -> m r r a
Files
- CHANGELOG.md +4/−0
- README.md +1/−1
- motor.cabal +2/−2
- src/Motor/FSM.hs +19/−3
- src/Motor/FSM/Class.hs +3/−0
- test/Motor/FSMSpec/Game.hs +5/−14
CHANGELOG.md view
@@ -0,0 +1,4 @@+* 0.1.1.0+ - Add `call` operation to `MonadFSM` class+* 0.1.0.0+ - Initial version of Motor
README.md view
@@ -3,7 +3,7 @@ *Motor* is an experimental Haskell library for building finite-state machines with type-safe transitions and effects. It draws inspiration from the Idris-[ST](http:/*docs.idris-lang.org*en*latest*st/state.html) library.+[ST](http://docs.idris-lang.org/en/latest/st/state.html) library. ## Usage
motor.cabal view
@@ -1,5 +1,5 @@ name: motor-version: 0.1.0.0+version: 0.1.1.0 synopsis: Type-safe effectful state machines in Haskell description:@@ -31,7 +31,7 @@ , Motor.FSM.Logging -- other-modules: -- other-extensions:- build-depends: base >=4.9 && <4.10+ build-depends: base >=4.9 && <5 , indexed , indexed-extras , CTRex
src/Motor/FSM.hs view
@@ -117,6 +117,7 @@ enter (Name :: Name n) x = FSM (imodify $ \s -> lbl := x .| (s .- lbl)) where lbl = Label :: Label n+ call (FSM ma) = FSM (ilift (fst <$> runIxStateT ma empty)) {- $usage The central finite-state machine abstraction in Motor is the 'MonadFSM' type class.@@ -287,11 +288,26 @@ >>>= \_ -> perish hero2 @ -This is obviously quite clumsy. If anyone has ideas on how to fix or-work around it, /please get in touch/.- Had the @r@ been replaced by @Empty@ in the type signature above, it could have had type @NoActions m Empty ()@ instead.++If the computation removes all resources that it creates, i.e. that it+could be run as @NoActions m Empty ()@, you can use 'call' to run it+in a row-polymorphic computation without having to list all actions:++@+doFourThings ::+ Game m+ => NoActions m r ()+doFourThings = call $+ spawn hero1+ >>>= \_ -> spawn hero2+ >>>= \_ -> perish hero1+ >>>= \_ -> perish hero2+@++In a future version, 'call' might support the rows of the called+computation being subsets of the resulting computation's rows. -}
src/Motor/FSM/Class.hs view
@@ -33,6 +33,9 @@ delete :: Name n -> m r (r :- n) () -- | Replaces the state of an existing resource named by its 'Name'. enter :: Name n -> b -> m r (n ::= b :| (r :- n)) ()+ -- | Run another 'MonadFSM' computation, with empty resource rows,+ -- in this computation.+ call :: m Empty Empty a -> m r r a -- | A name of a resource, represented using a 'Symbol'. data Name (n :: Symbol) where
test/Motor/FSMSpec/Game.hs view
@@ -10,7 +10,7 @@ {-# LANGUAGE TypeOperators #-} module Motor.FSMSpec.Game where -import Prelude hiding (log)+import Prelude hiding (log, (>>)) import Control.Monad.Indexed import Control.Monad.IO.Class@@ -87,12 +87,8 @@ testTwoAddDeletes :: Game m- => Actions m '[ "hero2" !- State m Standing- , "hero1" !- State m Standing- , "hero2" !+ State m Standing- , "hero1" !+ State m Standing- ] r ()-testTwoAddDeletes = do+ => NoActions m r ()+testTwoAddDeletes = call $ do spawn hero1 spawn hero2 perish hero1@@ -101,15 +97,10 @@ (>>) a = (>>>=) a . const testGame :: Game m => OnlyActions m '[] ()-testGame = testTwoAdds >> testTwoDeletes+testGame = testTwoAdds >> testTwoDeletes >> testTwoAddDeletes where (>>) a = (>>>=) a . const -run :: Monad m => GameImpl m Empty Empty () -> m ()-run g = runFSM (runGameImpl g)- runIO :: IO ()-runIO = do- run testGame- putStrLn "Game over."+runIO = runFSM (runGameImpl testGame)