diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright Oleg Grenrus (c) 2016
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Author name here nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+`Data.Functor.Classes` instances for core packages:
+
+- `containers`
+- `vector`
+- `unordered-containers`
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/functor-classes-compat.cabal b/functor-classes-compat.cabal
new file mode 100644
--- /dev/null
+++ b/functor-classes-compat.cabal
@@ -0,0 +1,147 @@
+name:                functor-classes-compat
+version:             1
+synopsis:            Data.Functor.Classes instances for core packages
+description:
+  "Data.Functor.Classes" instances for core packages:
+  .
+  * containers
+  .
+  * vector
+  .
+  * unordered-containers
+homepage:            https://github.com/phadej/functor-classes-compat#readme
+bug-reports:         https://github.com/phadej/functor-classes-compat/issues
+license:             BSD3
+license-file:        LICENSE
+author:              Oleg Grenrus <oleg.grenrus@iki.fi>
+maintainer:          Oleg Grenrus <oleg.grenrus@iki.fi>
+copyright:           2016 Oleg Grenrus
+category:            Data
+build-type:          Simple
+extra-source-files:  README.md
+cabal-version:       >=1.10
+tested-with:
+  GHC==7.4.2,
+  GHC==7.6.3,
+  GHC==7.8.4,
+  GHC==7.10.3,
+  GHC==8.0.1,
+  GHC==8.0.2
+
+flag base-transformers-1
+  description: Together with base-transformers-1 pick: base >= 4.9, transformers < 0.4, 0.4.*, or >= 0.5. See cabal file for precise assignments.
+  manual: False
+  default: True
+
+flag base-transformers-2
+  description: See base-transformers-1 flag
+  manual: False
+  default: True
+
+flag vector
+  description: 'vector >= 0.12'
+  manual: False
+  default: True
+
+flag containers
+  description: 'containers >= 0.5.9.1'
+  manual: False
+  default: True
+
+flag unordered-containers
+  description: 'unordered-containers >= 0.2.8.0'
+  manual: False
+  default: True
+
+source-repository head
+  type:     git
+  location: https://github.com/phadej/functor-classes-compat
+
+library
+  exposed-modules:
+    Data.Map.Functor.Classes
+    Data.Set.Functor.Classes
+    Data.IntMap.Functor.Classes
+    Data.Vector.Functor.Classes
+    Data.HashSet.Functor.Classes
+    Data.HashMap.Functor.Classes
+  default-language:    Haskell2010
+  ghc-options: -Wall
+
+  build-depends:  hashable >=1.0.1.1 && <1.3
+
+  -- base and transformer dependencies:
+  -- t t: base >= 4.9
+  -- t f: transformers >= 0.5
+  -- f t: transformers < 0.4
+  -- f f: transformers == 0.4.*
+  --
+  -- The order is chosen so 'f f' combination is only requiring src-old
+  if flag(base-transformers-1)
+    if flag(base-transformers-2)
+      build-depends: base         >=4.9 && <4.10
+    else
+      build-depends: base         >= 4.5 && <4.9,
+                     transformers >= 0.5 && <0.6
+  else
+    if flag(base-transformers-2)
+      -- we don't really care about transformers version, as long as it <0.4
+      -- to make flag selection deterministic
+      build-depends: base                >= 4.5 && <4.9,
+                     transformers        <  0.4,
+                     transformers-compat >= 0.5 && <0.6
+    else
+      build-depends: base                >= 4.5 && <4.9,
+                     transformers        >= 0.4 && <0.5
+
+
+  -- containers
+  if flag(containers)
+    build-depends: containers >= 0.5.9.1 && <0.6
+    if flag(base-transformers-1) && flag(base-transformers-2)
+        hs-source-dirs: src-none/containers
+    else
+      if !flag(base-transformers-1) && !flag(base-transformers-2)
+        hs-source-dirs: src-implicit/containers
+      else
+        hs-source-dirs: src-explicit/containers
+  else
+    build-depends: containers >= 0.4 && <0.5.9.1
+    if !flag(base-transformers-1) && !flag(base-transformers-2)
+      hs-source-dirs: src-implicit/containers
+    else
+      hs-source-dirs: src-explicit/containers
+
+  -- unordered-containers
+  if flag(unordered-containers)
+    build-depends: unordered-containers >= 0.2.8.0 && <0.3
+    if flag(base-transformers-1) && flag(base-transformers-2)
+        hs-source-dirs: src-none/unordered-containers
+    else
+      if !flag(base-transformers-1) && !flag(base-transformers-2)
+        hs-source-dirs: src-implicit/unordered-containers
+      else
+        hs-source-dirs: src-explicit/unordered-containers
+  else
+    build-depends: unordered-containers >= 0.2.7.1 && <0.2.8.0
+    if !flag(base-transformers-1) && !flag(base-transformers-2)
+      hs-source-dirs: src-implicit/unordered-containers
+    else
+      hs-source-dirs: src-explicit/unordered-containers
+
+  -- vector
+  if flag(vector)
+    build-depends: vector >= 0.12 && <0.13
+    if flag(base-transformers-1) && flag(base-transformers-2)
+        hs-source-dirs: src-none/vector
+    else
+      if !flag(base-transformers-1) && !flag(base-transformers-2)
+        hs-source-dirs: src-implicit/vector
+      else
+        hs-source-dirs: src-explicit/vector
+  else
+    build-depends: vector >= 0.11.0.0 && <0.12
+    if !flag(base-transformers-1) && !flag(base-transformers-2)
+      hs-source-dirs: src-implicit/vector
+    else
+      hs-source-dirs: src-explicit/vector
diff --git a/src-explicit/containers/Data/IntMap/Functor/Classes.hs b/src-explicit/containers/Data/IntMap/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-explicit/containers/Data/IntMap/Functor/Classes.hs
@@ -0,0 +1,27 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.IntMap.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.IntMap          (IntMap, fromList, size, toList)
+
+instance Eq1 IntMap where
+    liftEq eq m n =
+        size m == size n && liftEq (liftEq eq) (toList m) (toList n)
+
+instance Ord1 IntMap where
+    liftCompare cmp m n =
+        liftCompare (liftCompare cmp) (toList m) (toList n)
+
+instance Show1 IntMap where
+    liftShowsPrec sp sl d m =
+        showsUnaryWith (liftShowsPrec sp' sl') "fromList" d (toList m)
+      where
+        sp' = liftShowsPrec sp sl
+        sl' = liftShowList sp sl
+
+instance Read1 IntMap where
+    liftReadsPrec rp rl = readsData $
+        readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList
+      where
+        rp' = liftReadsPrec rp rl
+        rl' = liftReadList rp rl
diff --git a/src-explicit/containers/Data/Map/Functor/Classes.hs b/src-explicit/containers/Data/Map/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-explicit/containers/Data/Map/Functor/Classes.hs
@@ -0,0 +1,36 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.Map.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Map             (Map, fromList, size, toList)
+
+instance Eq2 Map where
+    liftEq2 eqk eqv m n =
+        size m == size n && liftEq (liftEq2 eqk eqv) (toList m) (toList n)
+
+instance Eq k => Eq1 (Map k) where
+    liftEq = liftEq2 (==)
+
+instance Ord2 Map where
+    liftCompare2 cmpk cmpv m n =
+        liftCompare (liftCompare2 cmpk cmpv) (toList m) (toList n)
+
+instance Ord k => Ord1 (Map k) where
+    liftCompare = liftCompare2 compare
+
+instance Show2 Map where
+    liftShowsPrec2 spk slk spv slv d m =
+        showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)
+      where
+        sp = liftShowsPrec2 spk slk spv slv
+        sl = liftShowList2 spk slk spv slv
+
+instance Show k => Show1 (Map k) where
+    liftShowsPrec = liftShowsPrec2 showsPrec showList
+
+instance (Ord k, Read k) => Read1 (Map k) where
+    liftReadsPrec rp rl = readsData $
+        readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList
+      where
+        rp' = liftReadsPrec rp rl
+        rl' = liftReadList rp rl
diff --git a/src-explicit/containers/Data/Set/Functor/Classes.hs b/src-explicit/containers/Data/Set/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-explicit/containers/Data/Set/Functor/Classes.hs
@@ -0,0 +1,17 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.Set.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Set             (Set, size, toList)
+
+instance Eq1 Set where
+    liftEq eq m n =
+        size m == size n && liftEq eq (toList m) (toList n)
+
+instance Ord1 Set where
+    liftCompare cmp m n =
+        liftCompare cmp (toList m) (toList n)
+
+instance Show1 Set where
+    liftShowsPrec sp sl d m =
+        showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)
diff --git a/src-explicit/unordered-containers/Data/HashMap/Functor/Classes.hs b/src-explicit/unordered-containers/Data/HashMap/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-explicit/unordered-containers/Data/HashMap/Functor/Classes.hs
@@ -0,0 +1,42 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.HashMap.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Hashable        (Hashable)
+import Data.HashMap.Strict  (HashMap, fromList, size, toList)
+
+import qualified Data.Map                 as M
+import           Data.Map.Functor.Classes ()
+
+-- | Unordered-containers don't export internals, so we cannot write correct `Eq2`
+-- instance. For the same reason, the context is over-restrictive too.
+instance Ord k => Eq1 (HashMap k) where
+    liftEq eqv m n =
+        size m == size n && equals eqv m n
+
+instance Show2 HashMap where
+    liftShowsPrec2 spk slk spv slv d m =
+        showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)
+      where
+        sp = liftShowsPrec2 spk slk spv slv
+        sl = liftShowList2 spk slk spv slv
+
+instance Show k => Show1 (HashMap k) where
+    liftShowsPrec = liftShowsPrec2 showsPrec showList
+
+instance (Eq k, Hashable k, Read k) => Read1 (HashMap k) where
+    liftReadsPrec rp rl = readsData $
+        readsUnaryWith (liftReadsPrec rp' rl') "fromList" fromList
+      where
+        rp' = liftReadsPrec rp rl
+        rl' = liftReadList rp rl
+
+-------------------------------------------------------------------------------
+-- unordered-containers don't expose internals, so this is difficult
+
+equals
+    :: Ord k
+    => (v -> v' -> Bool)
+    -> HashMap k v -> HashMap k v'
+    -> Bool
+equals eqv m n = liftEq eqv (M.fromList $ toList m) (M.fromList $ toList n)
diff --git a/src-explicit/unordered-containers/Data/HashSet/Functor/Classes.hs b/src-explicit/unordered-containers/Data/HashSet/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-explicit/unordered-containers/Data/HashSet/Functor/Classes.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.HashSet.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.HashSet         (HashSet, toList)
+
+instance Show1 HashSet where
+    liftShowsPrec sp sl d m =
+        showsUnaryWith (liftShowsPrec sp sl) "fromList" d (toList m)
diff --git a/src-explicit/vector/Data/Vector/Functor/Classes.hs b/src-explicit/vector/Data/Vector/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-explicit/vector/Data/Vector/Functor/Classes.hs
@@ -0,0 +1,20 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.Vector.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Vector          (Vector, fromList, length, toList)
+
+instance Eq1 Vector where
+    liftEq eq m n =
+        Data.Vector.length m == Data.Vector.length n && liftEq eq (toList m) (toList n)
+
+instance Ord1 Vector where
+    liftCompare cmp m n =
+        liftCompare cmp (toList m) (toList n)
+
+instance Show1 Vector where
+    liftShowsPrec _sp sl _d m = sl (toList m)
+
+instance Read1 Vector where
+    liftReadsPrec _rp rl _d s =
+        [ (fromList l, s') | (l, s') <- rl s ]
diff --git a/src-implicit/containers/Data/IntMap/Functor/Classes.hs b/src-implicit/containers/Data/IntMap/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-implicit/containers/Data/IntMap/Functor/Classes.hs
@@ -0,0 +1,10 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.IntMap.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.IntMap          (IntMap)
+
+instance Eq1 IntMap where eq1 = (==)
+instance Ord1 IntMap where compare1 = compare
+instance Show1 IntMap where showsPrec1 = showsPrec
+instance Read1 IntMap where readsPrec1 = readsPrec
diff --git a/src-implicit/containers/Data/Map/Functor/Classes.hs b/src-implicit/containers/Data/Map/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-implicit/containers/Data/Map/Functor/Classes.hs
@@ -0,0 +1,10 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.Map.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Map             (Map)
+
+instance Eq k => Eq1 (Map k) where eq1 = (==)
+instance Ord k => Ord1 (Map k) where compare1 = compare
+instance Show k => Show1 (Map k) where showsPrec1 = showsPrec
+instance (Ord k, Read k) => Read1 (Map k) where readsPrec1 = readsPrec
diff --git a/src-implicit/containers/Data/Set/Functor/Classes.hs b/src-implicit/containers/Data/Set/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-implicit/containers/Data/Set/Functor/Classes.hs
@@ -0,0 +1,9 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.Set.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Set             (Set)
+
+instance Eq1 Set where eq1 = (==)
+instance Ord1 Set where compare1 = compare
+instance Show1 Set where showsPrec1 = showsPrec
diff --git a/src-implicit/unordered-containers/Data/HashMap/Functor/Classes.hs b/src-implicit/unordered-containers/Data/HashMap/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-implicit/unordered-containers/Data/HashMap/Functor/Classes.hs
@@ -0,0 +1,10 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.HashMap.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Hashable        (Hashable)
+import Data.HashMap.Strict  (HashMap)
+
+instance Eq k => Eq1 (HashMap k) where eq1 = (==)
+instance Show k => Show1 (HashMap k) where showsPrec1 = showsPrec
+instance (Eq k, Hashable k, Read k) => Read1 (HashMap k) where readsPrec1 = readsPrec
diff --git a/src-implicit/unordered-containers/Data/HashSet/Functor/Classes.hs b/src-implicit/unordered-containers/Data/HashSet/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-implicit/unordered-containers/Data/HashSet/Functor/Classes.hs
@@ -0,0 +1,7 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.HashSet.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.HashSet         (HashSet)
+
+instance Show1 HashSet where showsPrec1 = showsPrec
diff --git a/src-implicit/vector/Data/Vector/Functor/Classes.hs b/src-implicit/vector/Data/Vector/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-implicit/vector/Data/Vector/Functor/Classes.hs
@@ -0,0 +1,10 @@
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+module Data.Vector.Functor.Classes () where
+
+import Data.Functor.Classes
+import Data.Vector          (Vector)
+
+instance Eq1 Vector where eq1 = (==)
+instance Ord1 Vector where compare1 = compare
+instance Show1 Vector where showsPrec1 = showsPrec
+instance Read1 Vector where readsPrec1 = readsPrec
diff --git a/src-none/containers/Data/IntMap/Functor/Classes.hs b/src-none/containers/Data/IntMap/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-none/containers/Data/IntMap/Functor/Classes.hs
@@ -0,0 +1,1 @@
+module Data.IntMap.Functor.Classes () where
diff --git a/src-none/containers/Data/Map/Functor/Classes.hs b/src-none/containers/Data/Map/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-none/containers/Data/Map/Functor/Classes.hs
@@ -0,0 +1,1 @@
+module Data.Map.Functor.Classes () where
diff --git a/src-none/containers/Data/Set/Functor/Classes.hs b/src-none/containers/Data/Set/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-none/containers/Data/Set/Functor/Classes.hs
@@ -0,0 +1,1 @@
+module Data.Set.Functor.Classes () where
diff --git a/src-none/unordered-containers/Data/HashMap/Functor/Classes.hs b/src-none/unordered-containers/Data/HashMap/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-none/unordered-containers/Data/HashMap/Functor/Classes.hs
@@ -0,0 +1,1 @@
+module Data.HashMap.Functor.Classes () where
diff --git a/src-none/unordered-containers/Data/HashSet/Functor/Classes.hs b/src-none/unordered-containers/Data/HashSet/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-none/unordered-containers/Data/HashSet/Functor/Classes.hs
@@ -0,0 +1,1 @@
+module Data.HashSet.Functor.Classes () where
diff --git a/src-none/vector/Data/Vector/Functor/Classes.hs b/src-none/vector/Data/Vector/Functor/Classes.hs
new file mode 100644
--- /dev/null
+++ b/src-none/vector/Data/Vector/Functor/Classes.hs
@@ -0,0 +1,1 @@
+module Data.Vector.Functor.Classes () where
