-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Utilities for accessing and manipulating fields of records -- -- In Haskell 98 the name of a record field is automatically also the -- name of a function which gets the value of the according field. E.g. -- if we have -- -- data Pair a b = Pair first :: a, second :: b -- -- then -- --
-- first :: Pair a b -> a -- second :: Pair a b -> b ---- -- However for setting or modifying a field value we need to use some -- syntactic sugar, which is often clumsy. -- -- modifyFirst :: (a -> a) -> (Pair a b -> Pair a b) modifyFirst -- f r@(Pair first=a ) = r first = f a -- -- With this package you can define record field accessors which allow -- setting, getting and modifying values easily. The package clearly -- demonstrates the power of the functional approach: You can combine -- accessors of a record and sub-records, to make the access look like -- the fields of the sub-record belong to the main record. -- -- Example: -- --
-- *Data.Accessor.Example> (first^:second^=10) (('b',7),"hallo")
-- (('b',10),"hallo")
--
--
-- You can easily manipulate record fields in a
-- Control.Monad.State.State monad, you can easily code
-- Show instances that use the Accessor syntax and you can parse
-- binary streams into records. See Data.Accessor.Example for
-- demonstration of all features.
--
-- It would be great if in revised Haskell versions the names of record
-- fields are automatically Data.Accessor.Accessors rather than
-- plain get functions. For now, the package
-- data-accessor-template provides Template Haskell functions
-- for automated generation of Data.Acesssor.Accessors. See also
-- the other data-accessor packages that provide an Accessor
-- interface to other data types. The package enumset provides
-- accessors to bit-packed records.
--
-- For similar packages see lenses and fclabel. A
-- related concept are editors
-- http://conal.net/blog/posts/semantic-editor-combinators/.
-- Editors only consist of a modify method (and modify applied
-- to a const function is a set function). This way, they
-- can modify all function values of a function at once, whereas an
-- accessor can only change a single function value, say, it can change
-- f 0 = 1 to f 0 = 2. This way, editors can even
-- change the type of a record or a function. An Arrow instance can be
-- defined for editors, but for accessors only a Category instance is
-- possible ('(.)' method). The reason is the arr method of the
-- Arrow class, that conflicts with the two-way nature (set and
-- get) of accessors.
@package data-accessor
@version 0.2.2.6
-- | This module defines the Accessor type. It should be imported
-- with qualification.
module Data.Accessor.Basic
-- | The accessor function we use, has a record value as first argument and
-- returns the content of a specific record field and a function that
-- allows to overwrite that field with a new value.
--
-- In former version of a package we used a function that resembled the
-- state monad. However this required to use an undefined in the
-- implementation of the get function.
data T r a
fromSetGet :: (a -> r -> r) -> (r -> a) -> T r a
fromLens :: (r -> (a, a -> r)) -> T r a
-- | If an object is wrapped in a newtype, you can generate an
-- Accessor to the unwrapped data by providing a wrapper and an
-- unwrapper function. The set function is simpler in this case, since no
-- existing data must be kept. Since the information content of the
-- wrapped and unwrapped data is equivalent, you can swap wrapper and
-- unwrapper. This way you can construct an Accessor that treats
-- a record field containing an unwrapped object like a field containing
-- a wrapped object.
--
--
-- newtype A = A {unA :: Int}
--
-- access :: Accessor.T A Int
-- access = fromWrapper A unA
--
--
-- We could also have called this function fromBijection, since
-- it must hold wrap . unwrap = id and unwrap . wrap =
-- id.
fromWrapper :: (b -> a) -> (a -> b) -> T a b
-- | Access the record itself
self :: T r r
-- | Access a (non-existing) element of type ()
null :: T r ()
-- | result a accesses the value of a function for argument
-- a. It is not very efficient to build a function from setting
-- all of its values using this accessor, since every access to a
-- function adds another if-then-else.
--
-- Also see semantic editor combinators, that allow to modify all
-- function values of a function at once. Cf.
-- http://conal.net/blog/posts/semantic-editor-combinators/
result :: Eq a => a -> T (a -> b) b
-- | Set the value of a field.
set :: T r a -> a -> r -> r
-- | set as infix operator. This lets us write first ^= 2+3 $
-- second ^= 5+7 $ record.
(^=) :: T r a -> a -> (r -> r)
-- | This is a general function, but it is especially useful for setting
-- many values of different type at once.
compose :: [r -> r] -> r -> r
-- | Get the value of a field.
get :: T r a -> r -> a
-- | get as infix operator. This lets us write
-- record^.field^.subfield. This imitates Modula II syntax.
(^.) :: r -> T r a -> a
-- | Transform the value of a field by a function.
modify :: T r a -> (a -> a) -> (r -> r)
-- | modify as infix operator. This lets us write
-- field^:subfield^:(2*) $ record,
-- record$%field^:subfield^:(2*) or
-- record$%field^:subfield^:(const 1).
(^:) :: T r a -> (a -> a) -> (r -> r)
-- | Accessor composition: Combine an accessor with an accessor to a
-- sub-field. Speak "stack".
(.>) :: T a b -> T b c -> T a c
-- | Accessor composition the other direction.
--
-- -- (<.) = flip (.>) ---- -- You may also use the (.) operator from Category class. (<.) :: T b c -> T a b -> T a c -- | Flipped version of '($)'. ($%) :: a -> (a -> b) -> b -- | Merge the accessors to two independent fields. -- -- Independency means, it must hold: -- --
-- set (merge accA accB) (a,b) = set (merge accB accA) (b,a) ---- -- You may construct smart accessors by composing a merged accessor with -- a fromWrapper accessor. -- -- This is a special case of the more general Point concept in -- the package fclabels. merge :: T a b -> T a c -> T a (b, c) -- | Access helper functions in a State monad -- | Deprecated: please use Data.Accessor.Monad.Trans.State from -- data-accessor-transformers module Data.Accessor.MonadState set :: Monad m => T r a -> a -> StateT r m () get :: Monad m => T r a -> StateT r m a modify :: Monad m => T r a -> (a -> a) -> StateT r m () -- | Modify a record element and return its old value. getAndModify :: Monad m => T r a -> (a -> a) -> StateT r m a -- | Modify a record element and return its new value. modifyAndGet :: Monad m => T r a -> (a -> a) -> StateT r m a -- | Infix variant of set. (%=) :: Monad m => T r a -> a -> StateT r m () -- | Infix variant of modify. (%:) :: Monad m => T r a -> (a -> a) -> StateT r m () lift :: Monad m => T r s -> State s a -> StateT r m a liftT :: Monad m => T r s -> StateT s m a -> StateT r m a -- | This module allows to access elements of arrays, sets and finite maps -- like elements of records. This is especially useful for working with -- nested structures consisting of arrays, sets, maps and records. -- -- Maybe we should move it to a separate package, then we would not need -- to import array and containers package. module Data.Accessor.Container array :: Ix i => i -> T (Array i e) e -- | Treat a Set like a boolean array. set :: Ord a => a -> T (Set a) Bool -- | Treats a finite map like an infinite map, where all undefined elements -- are replaced by a default value. mapDefault :: Ord key => elem -> key -> T (Map key elem) elem -- | Treats a finite map like an infinite map, where all undefined elements -- are Nothing and defined elements are Just. mapMaybe :: Ord key => key -> T (Map key elem) (Maybe elem) intMapDefault :: elem -> Int -> T (IntMap elem) elem intMapMaybe :: Int -> T (IntMap elem) (Maybe elem) -- | Support for creating Show instances using the accessors. module Data.Accessor.Show field :: (Show a, Eq a) => String -> T r a -> r -> r -> Maybe ShowS showsPrec :: [r -> r -> Maybe ShowS] -> String -> r -> Int -> r -> ShowS module Data.Accessor.Tuple -- | Access to the first value of a pair. first :: T (a, b) a -- | Access to the second value of a pair. second :: T (a, b) b -- | Access to the first value of a triple. first3 :: T (a, b, c) a -- | Access to the second value of a triple. second3 :: T (a, b, c) b -- | Access to the third value of a triple. third3 :: T (a, b, c) c -- | Reading records from streams -- -- This is still only for demonstration and might be of not much use and -- you should not rely on the interface. module Data.Accessor.BinaryRead type Stream = [Word8] class C a any :: (C a, ByteSource source) => source a class Monad source => ByteSource source readWord8 :: ByteSource source => source Word8 class ByteStream s getWord8 :: (ByteStream s, Monad m) => s -> m (Word8, s) class ByteCompatible byte toByte :: ByteCompatible byte => byte -> Word8 newtype Parser s r Parser :: ((r, s) -> Maybe (r, s)) -> Parser s r runParser :: Parser s r -> (r, s) -> Maybe (r, s) field :: (ByteStream s, C a) => T r a -> Parser s r record :: [Parser s r] -> Parser s r instance C Int instance C Char instance C Word8 instance (ByteStream s, Monad m) => ByteSource (StateT s m) instance ByteCompatible Word8 instance ByteCompatible byte => ByteStream [byte] -- | This module provides a simple abstract data type for a piece of a data -- stucture that can be read from and written to. In contrast to -- Data.Accessor.Basic it is intended for unqualified import. module Data.Accessor -- | An Accessor r a is an object that encodes how to get and put -- a subject of type a out of/into an object of type s. -- -- In order for an instance of this data structure a to be an -- Accessor, it must obey the following laws: -- --
-- getVal a (setVal a x r) = x -- setVal a (getVal a r) r = r --type Accessor r a = T r a -- | Construct an Accessor from a get and a set -- method. accessor :: (r -> a) -> (a -> r -> r) -> Accessor r a -- | Set a value of a record field that is specified by an Accessor setVal :: Accessor r a -> a -> r -> r -- | set as infix operator. This lets us write first ^= 2+3 $ -- second ^= 5+7 $ record. (^=) :: T r a -> a -> (r -> r) -- | Get a value from a record field that is specified by an Accessor getVal :: Accessor r a -> r -> a -- | get as infix operator. This lets us write -- record^.field^.subfield. This imitates Modula II syntax. (^.) :: r -> T r a -> a -- | modify as infix operator. This lets us write -- field^:subfield^:(2*) $ record, -- record$%field^:subfield^:(2*) or -- record$%field^:subfield^:(const 1). (^:) :: T r a -> (a -> a) -> (r -> r) -- | A structural dereference function for state monads. -- | Deprecated: Data.Accessor.Monad.Trans.State.get from -- data-accessor-transformers package getA :: Monad m => Accessor r a -> StateT r m a -- | A structural assignment function for state monads. -- | Deprecated: Data.Accessor.Monad.Trans.State.set from -- data-accessor-transformers package putA :: Monad m => Accessor r a -> a -> StateT r m () -- | An "assignment operator" for state monads. -- --
-- (=:) = putA ---- | Deprecated: use (Data.Accessor.Monad.Trans.State.%=) from -- data-accessor-transformers package (=:) :: Monad m => Accessor r a -> a -> StateT r m () -- | Infix variant of set. (%=) :: Monad m => T r a -> a -> StateT r m () -- | A structural modification function for state monads. -- | Deprecated: Data.Accessor.Monad.Trans.State.modify from -- data-accessor-transformers package modA :: Monad m => Accessor r a -> (a -> a) -> StateT r m () -- | Infix variant of modify. (%:) :: Monad m => T r a -> (a -> a) -> StateT r m () -- | Accessor composition: Combine an accessor with an accessor to a -- sub-field. Speak "stack". (.>) :: Accessor a b -> Accessor b c -> Accessor a c -- | Accessor composition the other direction. -- --
-- (<.) = flip (.>) ---- -- You may also use the (.) operator from Category class. (<.) :: Accessor b c -> Accessor a b -> Accessor a c