diff --git a/data-accessor.cabal b/data-accessor.cabal
--- a/data-accessor.cabal
+++ b/data-accessor.cabal
@@ -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>
diff --git a/src/Data/Accessor/Basic.hs b/src/Data/Accessor/Basic.hs
--- a/src/Data/Accessor/Basic.hs
+++ b/src/Data/Accessor/Basic.hs
@@ -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))
diff --git a/src/Data/Accessor/Container.hs b/src/Data/Accessor/Container.hs
--- a/src/Data/Accessor/Container.hs
+++ b/src/Data/Accessor/Container.hs
@@ -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,
diff --git a/src/Data/Accessor/Example.hs b/src/Data/Accessor/Example.hs
--- a/src/Data/Accessor/Example.hs
+++ b/src/Data/Accessor/Example.hs
@@ -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 =
