{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} -- | Syntactic sugar for 'MonadFSM' types. module Motor.FSM.Sugar ( Add(..) , Delete(..) , To(..) , (:->) , FromActions , NoActions , Actions , OnlyActions , type (!-->) , type (!+) , type (!-) ) where import Data.OpenRecords import GHC.TypeLits (Symbol) -- | Action that adds a new resource in state 's'. newtype Add s = Add s -- | Action that deletes an existing resource in state 's'. newtype Delete s = Delete s -- | Action that transitions the state of an existing resource from -- state 'a' to 'b'. data To a b = Transition a b -- | Mapping from 'Symbol' to some action 'k'. data (:->) (n :: Symbol) (a :: k) infixr 5 :-> -- | Translates a list of 'Action's to a 'Row'. type family FromActions (as :: [*]) (rs :: Row *) :: (Row *) where FromActions '[] rs = rs FromActions ((n :-> Add a) ': ts) r = Extend n a (FromActions ts r) FromActions ((n :-> Delete a) ': ts) r = FromActions ts r :- n FromActions ((n :-> To a b) ': ts) r = Extend n b (FromActions ts r :- n) -- | Alias for 'MonadFSM' that includes no actions. type NoActions m (r :: Row *) a = m r r a -- | Alias for 'MonadFSM' that uses 'FromActions' to construct rows. type Actions m as (r :: Row *) a = m r (FromActions as r) a -- | Alias for 'MonadFSM' that uses 'FromActions' to construct rows, -- starting from an 'Empty' row, i.e. allowing no /other/ resources. type OnlyActions m as a = Actions m as Empty a -- | Infix version of 'To'. type (!-->) i o = To i o infixl 6 !--> -- | Add a named resource. Alias of 'Add'. type (!+) (n :: Symbol) s = n :-> Add s infix 6 !+ -- | Delete a named resource. Alias of 'Delete'. type (!-) (n :: Symbol) s = n :-> Delete s infix 6 !-