Copyright | (c) Andrey Mulik 2020 |
---|---|
License | BSD-style |
Maintainer | work.a.mulik@gmail.com |
Safe Haskell | Safe |
Language | Haskell2010 |
Data.Property
new-style properties.
Synopsis
- class IsProp (prop :: PropertyKind) where
- performProp :: Monad m => record -> prop m field record -> m ()
- type PropertyKind = (Type -> Type) -> FieldKind -> Type -> Type
- type FieldKind = (Type -> Type) -> Type -> Type -> Type
- data Prop m field record where
- class FieldGet field where
- get :: (Monad m, FieldGet field) => field m record a -> record -> m a
- gets' :: (Monad m, FieldGet field) => record -> [field m record a] -> m [a]
- class FieldSet field where
- set :: Monad m => record -> [Prop m field record] -> m ()
- sets' :: Monad m => record -> [Prop m field record] -> m ()
- pattern (:=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> a -> Prop m field record
- pattern (::=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> (record -> a) -> Prop m field record
- pattern (:=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> a -> Prop m field record
- pattern (::=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> (record -> a) -> Prop m field record
- pattern (:<=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> m a -> Prop m field record
- pattern (:<=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> m a -> Prop m field record
- pattern (:=<) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> (record -> m a) -> Prop m field record
- pattern (:=<$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> (record -> m a) -> Prop m field record
- class FieldSet field => FieldModify field where
- modifyRecord :: Monad m => field m record a -> record -> (a -> a) -> m a
- modifyRecordM :: (Monad m, FieldGet field) => field m record a -> record -> (a -> m a) -> m a
- pattern (:~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => field m record a -> (a -> a) -> Prop m field record
- pattern (:~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => [field m record a] -> (a -> a) -> Prop m field record
- pattern (::~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => field m record a -> (record -> a -> a) -> Prop m field record
- pattern (::~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => [field m record a] -> (record -> a -> a) -> Prop m field record
- pattern (:<~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => field m record a -> (a -> m a) -> Prop m field record
- pattern (:<~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => [field m record a] -> (a -> m a) -> Prop m field record
- 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
- 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
- class IsSwitch switch where
- class FieldSwitch field where
- switchRecord :: (Monad m, IsSwitch a) => field m record a -> record -> Int -> m ()
- switch :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Int -> Prop m field record
- incr :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Prop m field record
- decr :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Prop m field record
Generalized properties
class IsProp (prop :: PropertyKind) where Source #
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.
Since: 0.2
performProp :: Monad m => record -> prop m field record -> m () Source #
performProp record prop
performs an action on record
using prop
.
type PropertyKind = (Type -> Type) -> FieldKind -> Type -> Type Source #
@since 0.2 Service kind synonym.
Basic properties
class FieldGet field where Source #
@since 0.2 Property getter class.
getRecord :: Monad m => field m record a -> record -> m a Source #
return getRecord
field recordrecord
's value using field
.
get :: (Monad m, FieldGet field) => field m record a -> record -> m a Source #
The get
function reads current value of a field.
gets' :: (Monad m, FieldGet field) => record -> [field m record a] -> m [a] Source #
returns list of gets'
fields recordrecord
fields
values.
class FieldSet field where Source #
@since 0.2 Property setter class.
setRecord :: Monad m => field m record a -> record -> a -> m () Source #
sets new setRecord
field record valuerecord
value
.
set :: Monad m => record -> [Prop m field record] -> m () Source #
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 properties
pattern (:=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> a -> Prop m field record Source #
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 -> (record -> a) -> Prop m field record Source #
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] -> a -> Prop m field record Source #
Pure group setter. set record [fields :=$ value]
set value
to record
's
some fields
.
set record [[field] :=$ value] === set record [field := value]
Since: 0.2
pattern (::=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> (record -> a) -> Prop m field record Source #
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]
Since: 0.2
Monadic set properties
pattern (:<=) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> m a -> Prop m field record Source #
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]
Since: 0.2
pattern (:<=$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> m a -> Prop m field record Source #
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]
Since: 0.2
pattern (:=<) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => field m record a -> (record -> m a) -> Prop m field record Source #
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]
Since: 0.2
pattern (:=<$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldSet field) => [field m record a] -> (record -> m a) -> Prop m field record Source #
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]
Since: 0.2
Modify properties
class FieldSet field => FieldModify field where Source #
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).
Since: 0.2
Nothing
modifyRecord :: Monad m => field m record a -> record -> (a -> a) -> m a Source #
modifies modifyRecord
field record updrecord
field
using upd
.
Returns new value.
default modifyRecord :: (Monad m, FieldGet field) => field m record a -> record -> (a -> a) -> m a Source #
modifyRecordM :: (Monad m, FieldGet field) => field m record a -> record -> (a -> m a) -> m a Source #
modifies modifyRecordM
field record updrecord
field
using upd
.
Note that assumes the possibility of old value "leaking", e.g.:
-- get value usingmodifyRecordM
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.
Instances
FieldModify Field Source # | |
Defined in Data.Field | |
FieldModify MField Source # | |
Defined in Data.MField | |
(FieldModify field, FieldGet field) => FieldModify (Observe field) Source # | |
Defined in Data.Field.Observe |
Modify properties
pattern (:~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => field m record a -> (a -> a) -> Prop m field record Source #
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 Source #
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]
Since: 0.2
pattern (::~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field) => field m record a -> (record -> a -> a) -> Prop m field record Source #
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 Source #
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]
Since: 0.2
Monadic modify properties
pattern (:<~) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => field m record a -> (a -> m a) -> Prop m field record Source #
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]
Since: 0.2
pattern (:<~$) :: (Typeable m, Typeable field, Typeable record, Monad m, FieldModify field, FieldGet field) => [field m record a] -> (a -> m a) -> Prop m field record Source #
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]
Since: 0.2
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 Source #
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]
Since: 0.2
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 Source #
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]
Since: 0.2
Switch properties
class IsSwitch switch where Source #
Service class for switchable types.
class FieldSwitch field where Source #
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
.
switchRecord :: (Monad m, IsSwitch a) => field m record a -> record -> Int -> m () Source #
Repeated increment or decrement.
Instances
FieldSwitch Field Source # | |
Defined in Data.Field | |
FieldSwitch MField Source # | |
Defined in Data.MField | |
FieldSwitch field => FieldSwitch (Observe field) Source # | |
Defined in Data.Field.Observe |
switch :: (Monad m, FieldSwitch field, IsSwitch a) => field m record a -> Int -> Prop m field record Source #
switch
changes the value by n steps.