data-accessor 0.2.1.8 → 0.2.2
raw patch · 4 files changed
+76/−9 lines, 4 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Data.Accessor.Basic: merge :: T a b -> T a c -> T a (b, c)
+ Data.Accessor.Container: set :: Ord a => a -> T (Set a) Bool
- Data.Accessor.Basic: result :: Eq a => a -> T (a -> r) r
+ Data.Accessor.Basic: result :: Eq a => a -> T (a -> b) b
Files
- data-accessor.cabal +1/−1
- src/Data/Accessor/Basic.hs +33/−4
- src/Data/Accessor/Container.hs +16/−3
- src/Data/Accessor/Example.hs +26/−1
data-accessor.cabal view
@@ -1,5 +1,5 @@ Name: data-accessor-Version: 0.2.1.8+Version: 0.2.2 License: BSD3 License-File: LICENSE Author: Henning Thielemann <haskell@henning-thielemann.de>, Luke Palmer <lrpalmer@gmail.com>
src/Data/Accessor/Basic.hs view
@@ -10,6 +10,7 @@ modify, (^:), (.>), (<.), ($%),+ merge, ) where import qualified Data.Accessor.Private as A@@ -42,12 +43,15 @@ > > 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 fromWrapper wrap unwrap = fromSetGet (const . wrap) unwrap -{-+{- test whether the example can be compiled newtype A = A {unA :: Int} access :: T A Int@@ -72,12 +76,15 @@ {- | @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 -> r) r+result :: Eq a => a -> T (a -> b) b result ai = fromSetGet (\r f a -> if a==ai then r else f a) ($ai) @@ -91,9 +98,7 @@ infixr 5 ^=, ^: -infixl 0 $% - {- | 'set' as infix operator. This lets us write @first ^= 2+3 $ second ^= 5+7 $ record@.@@ -154,9 +159,13 @@ (^:) :: T r a -> (a -> a) -> (r -> r) (^:) = modify ++infixl 0 $%+ {- | Flipped version of '($)'. -}+-- could be re-exported from utility-ht ($%) :: a -> (a -> b) -> b ($%) = flip ($) @@ -189,3 +198,23 @@ -} (<.) :: T b c -> T a b -> T a c (<.) = flip A.compose+++{- |+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)+merge accB accC =+ fromSetGet+ (\(b,c) -> set accB b . set accC c)+ (\a -> (get accB a, get accC a))
src/Data/Accessor/Container.hs view
@@ -1,11 +1,14 @@ {- |-This module allows to access elements of arrays and finite maps+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, maps and records.+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,+ (array, set, mapDefault, mapMaybe, intMapDefault, intMapMaybe, ) where@@ -14,6 +17,7 @@ import Data.Ix (Ix, ) import qualified Data.Array as Array+import qualified Data.Set as Set import qualified Data.Map as Map import qualified Data.IntMap as IntMap @@ -22,6 +26,15 @@ array :: Ix i => i -> Accessor.T (Array.Array i e) e array i = Accessor.fromSetGet (\e a -> a Array.// [(i,e)]) (Array.! i)++{- |+Treat a Set like a boolean array.+-}+set :: Ord a => a -> Accessor.T (Set.Set a) Bool+set a =+ Accessor.fromSetGet+ (\b -> if b then Set.insert a else Set.delete a)+ (Set.member a) {- | Treats a finite map like an infinite map,
src/Data/Accessor/Example.hs view
@@ -1,7 +1,7 @@ module Data.Accessor.Example where import Data.Accessor.Basic ((.>), ($%), (^.), (^:), (^=), )-import Data.Accessor.Tuple (first, second, )+import Data.Accessor.Tuple (first, second, first3, second3, ) import qualified Data.Accessor.Container as Container import qualified Data.Accessor.BinaryRead as Read@@ -9,6 +9,7 @@ import qualified Data.Accessor.Basic as Accessor import qualified Data.Array as Array+import qualified Data.Set as Set import qualified Data.Map as Map import Data.Char (ord, toUpper, )@@ -106,11 +107,35 @@ let f = (Accessor.result 0 ^: Accessor.result 0 ^= 1) div in map (uncurry f) [(4,2), (2,1), (0,0)] ++merge :: (Int, Char, Ordering)+merge =+ Accessor.merge first3 second3 ^= (42, 'c') $+ (23, 'a', GT)++accessHourMinute :: Accessor.T (Int, Int, Int) Int+accessHourMinute =+ Accessor.merge first3 second3 .>+ Accessor.fromWrapper (\h -> divMod h 60) (\(h,m) -> h*60+m)++mergeHourMinute :: (Int, Int, Int)+mergeHourMinute =+ accessHourMinute ^: (15+) $+ (12, 58, 13)++ array :: Array.Array Int Char array = Container.array 7 ^: toUpper $ Container.array 2 ^= 'z' $ Array.listArray (0,9) ['a'..]++set :: Set.Set Char+set =+ Container.set 'a' ^= False $+ Container.set 'd' ^: not $+ Container.set 'b' ^= True $+ Set.fromList ['a','c'] mapDefault :: Map.Map Int Char mapDefault =