diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,19 @@
-# FUTURE FEATUES
+# TODO
 * `HDiff` typeclass to authomatically calculate difference between two hsets
-* Use `Data.Set TypeRep Dynamic` as internal representation of hset to
+* Use `Data.Map TypeRep Dynamic` as internal representation of hset to
   increase access speed to arbitrary fields
 * Add lens support
 
 # CHANGELOG
+
+## 2.1.0
+### Changed
+* `hgetTagged` moved to module `Data.HSet.Get`
+* fixed fundep of `HModify`
+### Added
+* functions to work with tagged types in `Data.HSet.Modify`
+* type families to work with type lists, like `Union` `Replace`
+  `TagElem`
 
 ## 2.0.0
 ### Changed
diff --git a/hset.cabal b/hset.cabal
--- a/hset.cabal
+++ b/hset.cabal
@@ -1,5 +1,5 @@
 name:                hset
-version:             2.0.0
+version:             2.1.0
 synopsis:            Primitive list with elements of unique types.
 license:             BSD3
 license-file:        LICENSE
diff --git a/src/Data/HSet/Get.hs b/src/Data/HSet/Get.hs
--- a/src/Data/HSet/Get.hs
+++ b/src/Data/HSet/Get.hs
@@ -1,10 +1,12 @@
 module Data.HSet.Get
        ( HGet(..)
        , HGettable
+       , hgetTagged
        ) where
 
 import Data.HSet.Type
 import Data.HSet.TypeLevel
+import Data.Tagged
 
 #if !(MIN_VERSION_base(4, 8, 0))
 import Control.Applicative
@@ -43,3 +45,27 @@
 -- | Enables deriving of the fact that 'e' is contained within 'els' and it's
 -- safe to say that 'hget' can be performed on this particular pair.
 type HGettable els e = HGet els e (Index e els)
+
+
+{- |
+
+>>> let y = HSCons (Tagged 10 :: Tagged "x" Int) $ HSCons (Tagged 20 :: Tagged "y" Int) HSNil
+>>> y
+HSCons (Tagged 10) (HSCons (Tagged 20) (HSNil))
+
+>>> hgetTagged (Proxy :: Proxy "x") y :: Int
+10
+
+>>> hgetTagged (Proxy :: Proxy "y") y :: Int
+20
+
+-}
+
+hgetTagged :: forall proxy label e els
+            . (HGettable els (Tagged label e))
+           => proxy label
+           -> HSet els
+           -> e
+hgetTagged _ hset =
+  let x = hget hset
+  in unTagged (x :: Tagged label e)
diff --git a/src/Data/HSet/Modify.hs b/src/Data/HSet/Modify.hs
--- a/src/Data/HSet/Modify.hs
+++ b/src/Data/HSet/Modify.hs
@@ -3,10 +3,15 @@
        , HModifiable
        , HMonoModifiable
        , hMonoModify
+       , hModifyTagged
+       , hMonoModifyTagged
+       , hUntag
+       , hTag
        ) where
 
 import Data.HSet.Type
 import Data.HSet.TypeLevel
+import Data.Tagged
 
 #if !(MIN_VERSION_base(4, 8, 0))
 import Control.Applicative
@@ -15,7 +20,7 @@
 class (i ~ (Index e1 els1), i ~ (Index e2 els2))
       => HModify els1 els2 e1 e2 i
        | els1 i     -> e1  , els2 i     -> e2
-       , els1 e1 e2 -> els2, els2 e1 e2 -> els1 where
+       , els1 e1 e2 i -> els2, els2 e1 e2 i -> els1 where
   hmodify :: (e1 -> e2) -> HSet els1 -> HSet els2
 
 instance ('False ~ Elem e2 els)
@@ -42,3 +47,35 @@
             -> HSet els
             -> HSet els
 hMonoModify f h = hmodify f h
+
+hModifyTagged :: forall proxy l els1 els2 e1 e2
+               . (HModifiable els1 els2 (Tagged l e1) (Tagged l e2))
+              => proxy l
+              -> (e1 -> e2)
+              -> HSet els1
+              -> HSet els2
+hModifyTagged _ f = hmodify (fmap f :: Tagged l e1 -> Tagged l e2)
+
+hMonoModifyTagged :: forall proxy l els e
+                   . (HMonoModifiable els (Tagged l e))
+                   => proxy l
+                   -> (e -> e)
+                   -> HSet els
+                   -> HSet els
+hMonoModifyTagged _ f = hmodify (fmap f :: Tagged l e -> Tagged l e)
+
+hUntag :: forall proxy els1 els2 l e
+        . (HModifiable els1 els2 (Tagged l e) e)
+       => proxy l
+       -> proxy e
+       -> HSet els1
+       -> HSet els2
+hUntag _ _ = hmodify (unTagged :: Tagged l e -> e)
+
+hTag :: forall proxy els1 els2 l e
+      . (HModifiable els1 els2 e (Tagged l e))
+     => proxy l
+     -> proxy e
+     -> HSet els1
+     -> HSet els2
+hTag _ _ = hmodify (Tagged :: e -> Tagged l e)
diff --git a/src/Data/HSet/SubHSet.hs b/src/Data/HSet/SubHSet.hs
--- a/src/Data/HSet/SubHSet.hs
+++ b/src/Data/HSet/SubHSet.hs
@@ -2,13 +2,11 @@
        ( SubHSet(..)
        , SubHSettable
        , hnarrow
-       , hgetTagged
        ) where
 
 import Data.HSet.Get
 import Data.HSet.Type
 import Data.HSet.TypeLevel
-import Data.Tagged
 
 #if !(MIN_VERSION_base(4, 8, 0))
 import Control.Applicative
@@ -78,26 +76,3 @@
 hnarrow :: (SubHSettable els subels)
         => proxy subels -> HSet els -> HSet subels
 hnarrow _ = subHSet
-
-{- |
-
->>> let y = HSCons (Tagged 10 :: Tagged "x" Int) $ HSCons (Tagged 20 :: Tagged "y" Int) HSNil
->>> y
-HSCons (Tagged 10) (HSCons (Tagged 20) (HSNil))
-
->>> hgetTagged (Proxy :: Proxy "x") y :: Int
-10
-
->>> hgetTagged (Proxy :: Proxy "y") y :: Int
-20
-
--}
-
-hgetTagged :: forall proxy label e els
-            . (HGettable els (Tagged label e))
-           => proxy label
-           -> HSet els
-           -> e
-hgetTagged _ hset =
-  let x = hget hset
-  in unTagged (x :: Tagged label e)
diff --git a/src/Data/HSet/TypeLevel.hs b/src/Data/HSet/TypeLevel.hs
--- a/src/Data/HSet/TypeLevel.hs
+++ b/src/Data/HSet/TypeLevel.hs
@@ -8,13 +8,21 @@
        , TEq
        , Length
        , Append
+       , AppendUniq
+       , Union
+       , UnionList'
+       , UnionList
        , XReverse
        , Reverse
        , Delete
+       , Replace
+       , TagElem
        , And
        , HSubset
        ) where
 
+import Data.Tagged
+
 data Nat = Z | S Nat
 
 -- | Calculates to 'True if first type argument contained in second
@@ -57,11 +65,30 @@
   Append x '[] = x
   Append (x ': xs) ys = x ': (Append xs ys)
 
+-- | Append element to type list if element is not presented in list
+-- already
+type family AppendUniq (typs :: [*]) (typ :: *) :: [*] where
+  AppendUniq (t ': ts) t = t ': ts
+  AppendUniq (t ': ts) t1 = t ': (AppendUniq ts t1)
+  AppendUniq '[] t1 = '[t1]
+
+-- | Calculates union two lists
+type family Union (l1 :: [*]) (l2 :: [*]) :: [*] where
+  Union l1 '[] = l1
+  Union l1 (l ': ls) = Union (AppendUniq l1 l) ls
+
+type family UnionList' (acc :: [*]) (ls :: [[*]]) :: [*] where
+  UnionList' acc (e ': es) = UnionList' (Union acc e) es
+  UnionList' acc '[] = acc
+
+-- | Union list of lists of elements. Return just unique elements of
+-- each nested list
+type UnionList l = UnionList' '[] l
+
 type family XReverse (acc :: [*]) (l :: [*]) :: [*] where
   XReverse acc '[] = acc
   XReverse acc (e ': els) = XReverse (e ': acc) els
 
-
 -- | Reverse list of elements
 type Reverse a = XReverse '[] a
 
@@ -70,6 +97,15 @@
   Delete x '[] = '[]
   Delete x (x ': ys) = Delete x ys
   Delete x (y ': ys) = y ': (Delete x ys)
+
+-- | Replace first arbitrary element 'typ1' in type list with 'typ2'
+type family Replace (typ1 :: *) (typ2 :: *) (typs :: [*]) :: [*] where
+  Replace a b (a ': xs) = (b ': xs)
+  Replace a b (x ': xs) = x ': (Replace a b xs)
+
+-- | Wrap first element with __Tagged tag__
+type TagElem (tag :: k) (typ :: *) (typs :: [*])
+  = Replace typ (Tagged tag typ) typs
 
 type family And (a :: Bool) (b :: Bool) where
   And 'False x      = 'False
