-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Fields for Monadic Records library -- -- The generalized, extensible syntax of abstract monadic records. @package fmr @version 0.2 -- | Data.Property new-style properties. module Data.Property -- | IsProp is a property class that allows you to extend -- fmr syntax. Now you can create new property types and use it -- with existing in set list of actions. class IsProp (prop :: PropertyKind) -- | performProp record prop performs an action on -- record using prop. performProp :: (IsProp prop, Monad m) => record -> prop m field record -> m () -- | @since 0.2 Service kind synonym. type PropertyKind = (Type -> Type) -> FieldKind -> Type -> Type -- | @since 0.2 Service kind synonym. type FieldKind = (Type -> Type) -> Type -> Type -> Type -- | Prop is new, generalized and extensible property type -- (existential), which may contain any IsProp value. data Prop m field record [Prop] :: (Monad m, IsProp prop) => prop m field record -> Prop m field record -- | @since 0.2 Property getter class. class FieldGet field -- | getRecord field record return record's value -- using field. getRecord :: (FieldGet field, Monad m) => field m record a -> record -> m a -- | The get function reads current value of a field. get :: (Monad m, FieldGet field) => field m record a -> record -> m a -- | gets' fields record returns list of record -- fields values. gets' :: (Monad m, FieldGet field) => record -> [field m record a] -> m [a] -- | @since 0.2 Property setter class. class FieldSet field -- | setRecord field record value sets new record -- value. setRecord :: (FieldSet field, Monad m) => field m record a -> record -> a -> m () -- | set is the main function in fmr, which allows you to -- describe changing the value of a record as a sequence of operations on -- its fields, e.g. set :: Monad m => record -> [Prop m field record] -> m () -- | Just synonym for set. sets' :: Monad m => record -> [Prop m field record] -> m () -- | Pure value setter. set record [field := value] set -- value to record's field. pattern (:=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> a -> Prop m field record -- | Pure value setter with record. set record [field ::= -- f] set f record to record's field. -- --
--   set record [field ::= const val] === set record [field := val]
--   
--   
pattern (::=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> (record -> a) -> Prop m field record -- | Pure group setter. set record [fields :=$ value] set -- value to record's some fields. -- --
--   set record [[field] :=$ value] === set record [field := value]
--   
--   
pattern (:=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> a -> Prop m field record -- | Pure group setter with record. set record [fields ::=$ -- f] set f record to record's some -- fields. -- --
--   set record [[field] ::=$ f] === set record [field ::= f]
--   set record [fields ::=$ const val] === set record [fields :=$ val]
--   
--   
pattern (::=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> (record -> a) -> Prop m field record -- | Monadic value setter. set record [field :<= mvalue] set -- result of mvalue to record's field. Note -- that the mvalue is evaluated every time a field -- value is assigned. -- --
--   set record [field :<= return val] === set record [field := val]
--   set record [field :<= mval] === do val <- mval; set record [field :<= val]
--   
--   
pattern (:<=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> m a -> Prop m field record -- | Monadic group setter. set record [fields :<=$ mvalue] set -- result of mvalue to record's fields. Note -- that mvalue is evaluated only once, on the first assignment. -- Thus, the values of all the listed fields will be identical. -- --
--   set record [[field] :<=$ const f] === set record [field :<= val]
--   set record [fields :<=$ mval] === do val <- mval; set record [fields :<=$ val]
--   
--   
pattern (:<=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> m a -> Prop m field record -- | Monadic value setter with record. set record [field -- :=< mvalue] set result of mvalue record to -- record's field. Note that the mvalue is -- evaluated every time a field value is assigned. -- --
--   set record [field :=< const val] === set record [field :<= val]
--   set record [field :=< f] === do val <- f record; set record [field := val]
--   
--   
pattern (:=<) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> (record -> m a) -> Prop m field record -- | Monadic group setter with record. set record [fields -- :=<$ f] set result of f record to record's -- fields. Note that f record is evaluated only once, -- on the first assignment. Thus, the values of all the listed fields -- will be identical. -- --
--   set record [[field] :=<$ f] === set record [field :=< val]
--   set record [fields :=<$ const val] = set record [fields :=$ val]
--   set record [fields :=<$ f] === do val <- f record; set record [fields :=$ val]
--   
--   
pattern (:=<$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> (record -> m a) -> Prop m field record -- | Property modifier class. -- -- Note that FieldModifier doesn't go well with write-only -- fields, because modifyRecord returns new value, and -- modifyRecordM also assumes the possibility of old value -- "leaking" (hence the FieldGet constraint is imposed on it). class (FieldSet field) => FieldModify field -- | modifyRecord field record upd modifies record -- field using upd. Returns new value. modifyRecord :: (FieldModify field, Monad m, FieldGet field) => field m record a -> record -> (a -> a) -> m a -- | modifyRecord field record upd modifies record -- field using upd. Returns new value. modifyRecord :: (FieldModify field, Monad m) => field m record a -> record -> (a -> a) -> m a -- | modifyRecordM field record upd modifies -- record field using upd. Note that assumes -- the possibility of old value "leaking", e.g.: -- --
--   -- get value using modifyRecordM
--   getLeak = do
--     -- Some read-only fields
--     x <- newWriteOnly
--     y <- var Nothing
--     -- write current value to y and do not modify.
--     modifyRecordM this x ( val -> do set [this := Just val]; return val)
--     -- leaking: return current value of "write-only" record
--     get this y
--   
--   
-- -- So you cannot use it for write-only fields. modifyRecordM :: (FieldModify field, Monad m, FieldGet field) => field m record a -> record -> (a -> m a) -> m a -- | Pure value modifier. set record [field :~ f] modify value of -- record's field using f function. -- --
--   set record [field :~ const val] === set record [field := val]
--   
--   
pattern (:~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => field m record a -> (a -> a) -> Prop m field record -- | Pure group modifier. set record [fields :~$ f] modify values -- of record's fields using f function. -- --
--   set record [[field] :~$ val] === set record [field :~ val]
--   set record [fields :~$ const val] === set record [field :=$ val]
--   
--   
pattern (:~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => [field m record a] -> (a -> a) -> Prop m field record -- | Pure value modifier with record. set record [field ::~ -- f] modify value of record's field using f -- record function. -- --
--   set record [field ::~ const f] === set record [field :~ f]
--   
--   
pattern (::~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => field m record a -> (record -> a -> a) -> Prop m field record -- | Pure group modifier with record. set record [fields ::~$ -- f] modify values of record's fields using f -- record function. -- --
--   set record [[field] ::~$ f] === set record [field ::~ f]
--   set record [fields ::~$ const f] === set record [field :~$ f]
--   
--   
pattern (::~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => [field m record a] -> (record -> a -> a) -> Prop m field record -- | Monadic value modifier. set record [field :<~ f] modifies -- value of record's field using f procedure. -- Note that the mvalue is called every time a field -- value is assigned. -- --
--   set record [field :<~ return val] === set record [fields := val]
--   
--   
pattern (:<~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => field m record a -> (a -> m a) -> Prop m field record -- | Monadic group modifier. set record [fields :<~$ f] -- modifies values of record's fields using f -- procedure. -- --
--   set record [[field] :<~$ f] === set record [field :<~ f]
--   set record [fields :<~$ const mval] === set record [field :<=$ mval]
--   
--   
pattern (:<~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => [field m record a] -> (a -> m a) -> Prop m field record -- | Monadic value modifier with record. set record [field -- :<~ f] modifies value of record's field -- using f record procedure. Note that the f record is -- called every time a field value is assigned. -- --
--   set record [field :~< const f] === set record [fields :<~ f]
--   
--   
pattern (:~<) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => field m record a -> (record -> a -> m a) -> Prop m field record -- | Monadic group modifier with record. set record [fields -- :~<$ f] modifies values of record's fields -- using f record procedure. Note that the f record is -- called every time a field value is assigned. -- --
--   set record [field :~<$ const f] === set record [fields :<~$ f]
--   
--   
pattern (:~<$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => [field m record a] -> (record -> a -> m a) -> Prop m field record -- | Service class for switchable types. class IsSwitch switch -- | toggle s n "toggles" the state represented by the -- value s by n positions, for example: -- --
--   toggle n False = even n
--   toggle n  True = odd  n
--   toggle n  1234 = 1239 + n
--   
--   
toggle :: IsSwitch switch => Int -> switch -> switch -- | Switch property modifier. -- -- Note that FieldSwitch is designed for deterministic switches -- with a pre-known set of states and order of transitions between them, -- without branches. If you need more complex behavior, use -- FieldModify. class FieldSwitch field -- | Repeated increment or decrement. switchRecord :: (FieldSwitch field, Monad m, IsSwitch a) => field m record a -> record -> Int -> m () -- | switch changes the value by n steps. switch :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Int -> Prop m field record -- | incr field is same as switch field 1. incr :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Prop m field record -- | decr field is same as switch field (-1). decr :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Prop m field record instance Data.Property.IsProp Data.Property.SwitchProp instance Data.Property.IsSwitch GHC.Types.Bool instance GHC.Real.Integral i => Data.Property.IsSwitch i instance Data.Property.IsProp Data.Property.ModifyProp instance Data.Property.IsProp Data.Property.SetProp -- | Data.Field.Observe simple field observer. module Data.Field.Observe -- | Simple field observer, which can run some handlers after each action. data Observe field m record a Observe :: field m record a -> (record -> a -> m ()) -> (record -> a -> m ()) -> (record -> m ()) -> Observe field m record a -- | Field to observe. [observed] :: Observe field m record a -> field m record a -- | getRecord observer [onGet] :: Observe field m record a -> record -> a -> m () -- | setRecord observer [onSet] :: Observe field m record a -> record -> a -> m () -- | modifyRecord observer [onModify] :: Observe field m record a -> record -> m () -- | Create field with default observers. observe :: Monad m => field m record a -> Observe field m record a instance Data.Property.FieldSwitch field => Data.Property.FieldSwitch (Data.Field.Observe.Observe field) instance Data.Property.FieldGet field => Data.Property.FieldGet (Data.Field.Observe.Observe field) instance Data.Property.FieldSet field => Data.Property.FieldSet (Data.Field.Observe.Observe field) instance (Data.Property.FieldModify field, Data.Property.FieldGet field) => Data.Property.FieldModify (Data.Field.Observe.Observe field) -- | Data.Field provides immutable field type for record-style -- operations. module Data.Field -- | Normal field, which contain getter, setter and modifier. -- -- Since fmr-0.2, you can also combine fmr fields using -- (.) and id from the Category -- class: -- --
--   outer :: (Monad m) => Field m outer inner
--   inner :: (Monad m) => Field m inner value
--   
--   field :: (Monad m) => Field m outer value
--   field =  outer.inner
--   
--   
data Field m record a Field :: !GetterFor m record a -> !SetterFor m record a -> !ModifierFor m record a -> !ModifierMFor m record a -> Field m record a -- | Field getter [getField] :: Field m record a -> !GetterFor m record a -- | Field setter [setField] :: Field m record a -> !SetterFor m record a -- | Field modifier [modifyField] :: Field m record a -> !ModifierFor m record a -- | Monadic field modifier [modifyFieldM] :: Field m record a -> !ModifierMFor m record a -- | sfield creates new field from given getter and setter. sfield :: Monad m => GetterFor m record a -> SetterFor m record a -> Field m record a -- | Getter type. type GetterFor m record a = record -> m a -- | Setter type. type SetterFor m record a = record -> a -> m () -- | Modifier type. type ModifierFor m record a = record -> (a -> a) -> m a -- | Monadic modifier type. type ModifierMFor m record a = record -> (a -> m a) -> m a -- | The IsMVar class provides this field for entire record -- access. -- -- Please note that you cannot create IsMVar and MonadVar -- instances for some monad separately. class (Monad m, MonadVar m) => IsMVar m var -- | this is common variable access field. this :: IsMVar m var => Field m (var a) a -- | Create and initialize new mutable variable. var :: IsMVar m var => a -> m (var a) -- | MonadVar is a class of monads for which defined at least one -- type of mutable variable. -- -- Note that a variable of type (Var m) should be as simple -- possible for a given monad. I only has to implement the basic -- operations triad: read, write and update (which don't have to be -- atomic). class (Monad m, IsMVar m (Var m)) => MonadVar m where { -- | (Var m) is type of mutable variable in monad -- m. type family Var m :: Type -> Type; } instance Data.Field.IsMVar (GHC.ST.ST s) (GHC.STRef.STRef s) instance Data.Field.IsMVar GHC.Types.IO GHC.IORef.IORef instance Data.Field.IsMVar GHC.Types.IO GHC.MVar.MVar instance Data.Field.IsMVar GHC.Conc.Sync.STM GHC.Conc.Sync.TVar instance Data.Field.MonadVar (GHC.ST.ST s) instance Data.Field.MonadVar GHC.Types.IO instance Data.Field.MonadVar GHC.Conc.Sync.STM instance GHC.Base.Monad m => Control.Category.Category (Data.Field.Field m) instance Data.Property.FieldGet Data.Field.Field instance Data.Property.FieldSet Data.Field.Field instance Data.Property.FieldModify Data.Field.Field instance Data.Property.FieldSwitch Data.Field.Field -- | Data.MField provides mutable field type for record-style -- operations. module Data.MField -- | MField represents field with mutable value and accessors. -- Unlike fields of type Field, MField fields are -- undesirable (and sometimes impossible) to be stored in the global -- environment. The dynamic nature of MField means changing -- accessors for specific records, so accessors do not contain a record -- argument. -- -- MField isn't designed for accessing external abstract objects -- and interfaces, it doesn't give the same freedom as Field, but -- at the same time it allows you to create flexible connections between -- fields and values without having to reconcile them. -- -- MField contains a function that takes a record and returns an -- MFieldRef. -- -- Example: -- --
--   newtype HasField a = HasField {someField :: MFieldRep IO a}
--   
--   field :: MField IO (HasField a) a
--   field =  MField (ref.someField)
--   
--   main :: IO ()
--   main =  do
--     putStrLn "Put some number"
--     record <- fmap HasField $ link =<< var =<< readLn :: IO (HasField Integer)
--     print =<< get field record
--     
--     set record [getter field :~ fmap (* 2)]
--     print =<< get field record
--   
--   
data MField m record a [MField] :: MonadVar m => (record -> MFieldRef m a) -> MField m record a class IsRef ref -- | Create new reference to the given variable. link :: (IsRef ref, MonadVar m) => Var m a -> m (ref m a) -- | Get an associated MFieldRef reference to the given reference. ref :: (IsRef ref, MonadVar m) => ref m a -> MFieldRef m a -- | MFieldRef is a structure containing accessors for a specific -- field of a specific record. As a rule, it makes sense to store -- MFieldRef in the record to which it refers. data MFieldRef m a -- | MFieldRep is a helper type that stores a variable and its -- accessors. data MFieldRep m a getter :: MField m record a -> Field m record (m a) setter :: MField m record a -> Field m record (a -> m ()) modifier :: MField m record a -> Field m record ((a -> a) -> m a) modifierM :: MField m record a -> Field m record ((a -> m a) -> m a) instance Data.MField.IsRef Data.MField.MFieldRep instance Data.Property.FieldGet Data.MField.MField instance Data.Property.FieldSet Data.MField.MField instance Data.Property.FieldModify Data.MField.MField instance Data.Property.FieldSwitch Data.MField.MField instance Data.MField.IsRef Data.MField.MFieldRef