packages feed

data-accessor 0.2.0.2 → 0.2.1

raw patch · 8 files changed

+190/−87 lines, 8 filesdep ~arraydep ~basedep ~containersPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: array, base, containers

API changes (from Hackage documentation)

+ Data.Accessor.Basic: fromWrapper :: (b -> a) -> (a -> b) -> T a b
+ Data.Accessor.Basic: result :: (Eq a) => a -> T (a -> r) r

Files

+ RegExp view
@@ -0,0 +1,17 @@+Poor man's Template Haskell -+Here are Regular expression for replacement in NEdit:+Write data declaration like++data T =+   Cons {+      fieldA_ :: String,+      fieldB_ :: Int+   }++Copy the body of the 'data' declaration to where you want to define accessors.+Remove comments at the end of each field.+Use the first line as the pattern to find+and the second line for the pattern to replace by.++^\s*(\w+)_( *):: (.+?),?\n+\1 :: Accessor.T T \3\n\1 =\n   Accessor.fromSetGet (\\x c -> c{\1_ = x}) \1_\n\n
data-accessor.cabal view
@@ -1,5 +1,5 @@ Name:             data-accessor-Version:          0.2.0.2+Version:          0.2.1 License:          BSD3 License-File:     LICENSE Author:           Henning Thielemann <haskell@henning-thielemann.de>, Luke Palmer <lrpalmer@gmail.com>@@ -7,9 +7,6 @@ Homepage:         http://www.haskell.org/haskellwiki/Record_access Package-URL:      http://code.haskell.org/data-accessor/ Category:         Data--- Portability:      Haskell98-Build-Type:       Simple-Build-Depends:    base>=1.0, array >=0.1 && <1, containers >=0.1 && <1, transformers >=0.0.1 && <0.2 Synopsis:         Utilities for accessing and manipulating fields of records Description:   In Haskell 98 the name of a record field@@ -42,25 +39,64 @@   > (('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+  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.Accessor's   rather than plain @get@ functions.-  The package @data-accessor-template@ provides Template Haskell functions+  For now, the package @data-accessor-template@ provides Template Haskell functions   for automated generation of 'Data.Acesssor.Accessor's.-GHC-Options:      -Wall+  .+  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 define 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.+-- Portability:      Haskell98+Cabal-Version:    >=1.2 Tested-With:      GHC==6.4.1 && ==6.8.2-Hs-Source-Dirs:   src-Exposed-Modules:-  Data.Accessor-  Data.Accessor.Basic-  Data.Accessor.Container-  Data.Accessor.Show-  Data.Accessor.Tuple-  Data.Accessor.BinaryRead-  Data.Accessor.MonadState-Other-Modules:-  Data.Accessor.Example+Build-Type:       Simple++Extra-Source-Files:+  RegExp+  src-3/Data/Accessor/Private.hs+  src-4/Data/Accessor/Private.hs++Flag category+  description: Check whether Arrow class is split into Arrow and Category.++Library+  Build-Depends:+    array >=0.1 && <0.3,+    containers >=0.1 && <0.3,+    transformers >=0.0.1 && <0.2+  If flag(category)+    Hs-Source-Dirs: src-4+    Build-Depends: base >= 4 && <6+  Else+    Hs-Source-Dirs: src-3+    Build-Depends: base >= 1 && <4++  GHC-Options:      -Wall+  Hs-Source-Dirs:   src+  Exposed-Modules:+    Data.Accessor+    Data.Accessor.Basic+    Data.Accessor.Container+    Data.Accessor.Show+    Data.Accessor.Tuple+    Data.Accessor.BinaryRead+    Data.Accessor.MonadState+  Other-Modules:+    Data.Accessor.Example+    Data.Accessor.Private
+ src-3/Data/Accessor/Private.hs view
@@ -0,0 +1,19 @@+module Data.Accessor.Private where++{- |+The access functions we propose, look very similar to those+needed for List.mapAccumL (but parameter order is swapped) and State monad.+They get the new value of the field and the record+and return the old value of the field and the record with the updated field.+-}+newtype T r a  =  Cons {decons :: a -> r -> (a, r)}++compose :: T a b -> T b c -> T a c+compose f g = Cons $ \ cNew aOld ->+   let (bOld, aNew) = decons f bNew aOld+       (cOld, bNew) = decons g cNew bOld+   in  (cOld, aNew)++self :: T r r+self = Cons $ \ai ri -> (ri, ai)+
+ src-4/Data/Accessor/Private.hs view
@@ -0,0 +1,26 @@+module Data.Accessor.Private where++import qualified Control.Category as C+++{- |+The access functions we propose, look very similar to those+needed for List.mapAccumL (but parameter order is swapped) and State monad.+They get the new value of the field and the record+and return the old value of the field and the record with the updated field.+-}+newtype T r a  =  Cons {decons :: a -> r -> (a, r)}++compose :: T a b -> T b c -> T a c+compose f g = Cons $ \ cNew aOld ->+   let (bOld, aNew) = decons f bNew aOld+       (cOld, bNew) = decons g cNew bOld+   in  (cOld, aNew)++self :: T r r+self = Cons $ \ai ri -> (ri, ai)+++instance C.Category T where+   id = self+   (.) = flip compose
src/Data/Accessor.hs view
@@ -75,6 +75,8 @@   infix 1 =:++{-# DEPRECATED (=:) "use (Data.Accessor.Monad.Trans.State.%=) from data-accessor-transformers package" #-} {- | An \"assignment operator\" for state monads. @@ -84,32 +86,17 @@ (=:) = putA  -{--infix 1 %=, %:--{- |-Another infix variant of 'putA'-that provides more consistency with the infix operators for records-(without State monad).--}-(%=) :: Monad m => Accessor r a -> a -> StateT r m ()-(%=) = putA--{- |-Infix variant of 'modA'.--}-(%:) :: Monad m => Accessor r a -> (a -> a) -> StateT r m ()-(%:) = modA--}---- |A structural dereference function for state monads.+{-# DEPRECATED getA "Data.Accessor.Monad.Trans.State.get from data-accessor-transformers package" #-}+-- | A structural dereference function for state monads. getA :: Monad m => Accessor r a -> StateT r m a getA = State.get --- |A structural assignment function for state monads.+{-# DEPRECATED putA "Data.Accessor.Monad.Trans.State.set from data-accessor-transformers package" #-}+-- | A structural assignment function for state monads. putA :: Monad m => Accessor r a -> a -> StateT r m () putA = State.set --- |A structural modification function for state monads.+{-# DEPRECATED modA "Data.Accessor.Monad.Trans.State.modify from data-accessor-transformers package" #-}+-- | A structural modification function for state monads. modA :: Monad m => Accessor r a -> (a -> a) -> StateT r m () modA = State.modify
src/Data/Accessor/Basic.hs view
@@ -3,8 +3,8 @@ It should be imported with qualification. -} module Data.Accessor.Basic (-   T, fromSetGet, fromLens,-   self, null,+   T, fromSetGet, fromLens, fromWrapper,+   self, null, result,    set, (^=), compose,    get, (^.),    modify, (^:),@@ -12,19 +12,13 @@    ($%),    ) where +import qualified Data.Accessor.Private as A+import Data.Accessor.Private (T(..), ) import Prelude hiding (null)   -- * Define and construct accessors -{- |-The access functions we propose, look very similar to those-needed for List.mapAccumL (but parameter order is swapped) and State monad.-They get the new value of the field and the record-and return the old value of the field and the record with the updated field.--}-newtype T r a  =  Cons {decons :: a -> r -> (a, r)}- fromSetGet :: (a -> r -> r) -> (r -> a) -> T r a fromSetGet setF getF =    Cons $ \x r -> (getF r, setF x r)@@ -33,14 +27,43 @@ fromLens lens =    Cons $ \ x r -> let (y,f) = lens r in (y, f x) +{- |+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+-}+fromWrapper :: (b -> a) -> (a -> b) -> T a b+fromWrapper wrap unwrap =+   fromSetGet (const . wrap) unwrap++{-+newtype A = A {unA :: Int}++access :: T A Int+access = fromWrapper A unA+-}++ -- Simple accessors  {- | Access the record itself -} self :: T r r-self = fromSetGet const id+self = A.self+-- self = fromSetGet const id  {- | Access a (non-existing) element of type @()@@@ -48,14 +71,16 @@ null :: T r () null = fromSetGet (flip const) (const ()) -{- {- |-Access the result of a function.-Cf. "http://conal.net/blog/posts/semantic-editor-combinators/"--}-result :: a -> T (a -> r) r-result = fromSetGet (flip const) (const ())+@result a@ accesses the value of a function for argument @a@.++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 -> r) r+result ai =+   fromSetGet (\r f a -> if a==ai then r else f a) ($ai)   -- * Apply accessors, similar to State methods@@ -147,12 +172,13 @@ Speak \"stack\". -} (.>) :: T a b -> T b c -> T a c-(.>) f g = Cons $ \ cNew aOld ->-   let (bOld, aNew) = decons f bNew aOld-       (cOld, bNew) = decons g cNew bOld-   in  (cOld, aNew)+(.>) = A.compose +{-+This could be used for a Category instance of T.+-} + infixr 9 <.  {- |@@ -161,4 +187,4 @@ > (<.) = flip (.>) -} (<.) :: T b c -> T a b -> T a c-(<.) = flip (.>)+(<.) = flip A.compose
src/Data/Accessor/Example.hs view
@@ -11,9 +11,6 @@ import qualified Data.Array as Array import qualified Data.Map   as Map -import Data.Accessor.MonadState ((%=), (%:), )-import qualified Data.Accessor.MonadState as AState-import Control.Monad.Trans.State (State) import Data.Char (ord, toUpper, )  import Prelude hiding (init)@@ -29,28 +26,6 @@    Accessor.set first 'a' $    ('b',7) -state :: State (Char,Int) Int-state =-   do AState.set first 'a'-      AState.modify second succ-      AState.get second--stateInfix :: State ((Char, Int), String) Int-stateInfix =-   do str <- AState.get second-      first.>first %= 'a'-      first.>second %: succ-      first.>first %= 'b'-      second %= '!' : str-      AState.get (first.>second)--stateLift :: State (Int, (Bool, Char)) ()-stateLift = do-  first %= 42-  AState.lift second $ do-    first  %: not-    second %= 'q'- init :: (Char,Int) init =    Accessor.compose@@ -115,6 +90,21 @@ null :: Char null = Accessor.null ^= () $ 'a' +{- |+Modify a value of the 'ord' function.+-}+result :: [Int]+result =+   let f = (Accessor.result 'a' ^= 65) ord+   in  map f "abcABC"++{- |+Modify a value of a curried function.+-}+result2 :: [Int]+result2 =+   let f = (Accessor.result 0 ^: Accessor.result 0 ^= 1) div+   in  map (uncurry f) [(4,2), (2,1), (0,0)]  array :: Array.Array Int Char array =
src/Data/Accessor/MonadState.hs view
@@ -1,5 +1,7 @@ {- | Access helper functions in a State monad -}-module Data.Accessor.MonadState where+module Data.Accessor.MonadState+   {-# DEPRECATED "please use Data.Accessor.Monad.Trans.State from data-accessor-transformers" #-}+   where  import qualified Data.Accessor.Basic as Accessor import qualified Control.Monad.Trans.State as State