diff --git a/Control/Categorical/Functor.hs b/Control/Categorical/Functor.hs
new file mode 100644
--- /dev/null
+++ b/Control/Categorical/Functor.hs
@@ -0,0 +1,94 @@
+{-# LANGUAGE RankNTypes #-}
+
+module Control.Categorical.Functor where
+
+import Control.Category.Dual
+import Control.Category.Groupoid
+import qualified Data.Functor as Base
+import Data.Functor.Compose
+import Data.Functor.Identity
+import Data.Functor.Const
+import Data.Functor.Product
+import Data.Functor.Sum
+import Data.Proxy
+
+class (Category s, Category t) => Functor (s :: α -> α -> *) (t :: β -> β -> *) (f :: α -> β) where
+    map :: s a b -> t (f a) (f b)
+
+{-# DEPRECATED EndoFunctor "Use Endofunctor" #-}
+type EndoFunctor s = Functor s s
+type Endofunctor s = Functor s s
+
+infixl 4 <$>
+(<$>) :: Functor s (->) f => s a b -> f a -> f b
+(<$>) = map
+
+newtype NT s f g = NT { nt :: ∀ a . s (f a) (g a) }
+
+instance Category s => Category (NT s) where
+    id = NT id
+    NT f . NT g = NT (f . g)
+
+instance Groupoid s => Groupoid (NT s) where
+    invert (NT f) = NT (invert f)
+
+instance {-# INCOHERENT #-} Base.Functor f => Functor (->) (->) f where map = Base.fmap
+
+instance Functor s (->) f => Functor (NT s) (NT (->)) (Compose f) where
+    map (NT f) = NT (\ (Compose x) -> Compose (f <$> x))
+
+instance Functor (NT (->)) (NT (NT (->))) Compose where
+    map (NT f) = NT (NT (\ (Compose x) -> Compose (f x)))
+
+instance (Functor s (->) f, Functor s (->) g) => Functor s (->) (Sum f g) where
+    map f (InL x) = InL (f <$> x)
+    map f (InR y) = InR (f <$> y)
+
+instance Functor (NT (->)) (NT (->)) (Sum f) where
+    map (NT f) = NT (\ case InL x -> InL x
+                            InR y -> InR (f y))
+
+instance Functor (NT (->)) (NT (NT (->))) Sum where
+    map (NT f) = NT (NT (\ case InL x -> InL (f x)
+                                InR y -> InR y))
+
+instance (Functor s (->) f, Functor s (->) g) => Functor s (->) (Product f g) where
+    map f (Pair x y) = Pair (f <$> x) (f <$> y)
+
+instance Functor (NT (->)) (NT (->)) (Product f) where
+    map (NT f) = NT (\ (Pair x y) -> Pair x (f y))
+
+instance Functor (NT (->)) (NT (NT (->))) Product where
+    map (NT f) = NT (NT (\ (Pair x y) -> Pair (f x) y))
+
+instance Category s => Functor s (->) (Const a) where
+    map _ (Const a) = Const a
+
+instance Functor (->) (NT (->)) Const where
+    map f = NT (\ (Const a) -> Const (f a))
+
+instance Functor (->) (->) Identity where
+    map f (Identity a) = Identity (f a)
+
+instance Category s => Functor s (->) Proxy where
+    map _ Proxy = Proxy
+
+instance Functor (->) (->) ((,) a) where
+    map f (a, b) = (a, f b)
+
+instance Functor (->) (NT (->)) (,) where
+    map f = NT (\ (a, b) -> (f a, b))
+
+instance Functor (->) (->) (Either a) where
+    map _ (Left a) = Left a
+    map f (Right b) = Right (f b)
+
+instance Functor (->) (NT (->)) Either where
+    map f = NT (\ case Left a -> Left (f a)
+                       Right b -> Right b)
+
+instance Category s => Functor s (->) (s a) where
+    map = (.)
+
+instance Category s => Functor (Dual s) (NT (->)) s where
+    map (Dual f) = NT (. f)
diff --git a/Control/Category/Const2.hs b/Control/Category/Const2.hs
new file mode 100644
--- /dev/null
+++ b/Control/Category/Const2.hs
@@ -0,0 +1,14 @@
+module Control.Category.Const2 where
+
+import Algebra as A
+import Control.Category.Groupoid
+
+newtype Const2 a b c = Const2 a
+  deriving (Semigroup, Monoid, Group)
+
+instance Monoid a => Category (Const2 a) where
+    id = Const2 mempty
+    Const2 a . Const2 b = Const2 (a <> b)
+
+instance Group a => Groupoid (Const2 a) where
+    invert (Const2 a) = Const2 (A.invert a)
diff --git a/Control/Category/Dual.hs b/Control/Category/Dual.hs
--- a/Control/Category/Dual.hs
+++ b/Control/Category/Dual.hs
@@ -2,7 +2,8 @@
 
 import Control.Category.Groupoid
 
-newtype Dual k a b = Dual { dual :: k b a } deriving (Data, Typeable)
+newtype Dual k a b = Dual { dual :: k b a }
+  deriving (Semigroup, Monoid, Group)
 
 instance Category k => Category (Dual k) where
     id = Dual id
diff --git a/Control/Category/Groupoid.hs b/Control/Category/Groupoid.hs
--- a/Control/Category/Groupoid.hs
+++ b/Control/Category/Groupoid.hs
@@ -1,9 +1,4 @@
-{-# LANGUAGE GADTs #-}
-
 module Control.Category.Groupoid where
 
 class Category k => Groupoid k where
     invert :: k a b -> k b a
-
-instance Groupoid (:~:) where
-    invert Refl = Refl
diff --git a/Data/Morphism/Endo.hs b/Data/Morphism/Endo.hs
--- a/Data/Morphism/Endo.hs
+++ b/Data/Morphism/Endo.hs
@@ -4,7 +4,6 @@
 import Control.Category.Groupoid as C
 
 newtype Endo s a = Endo { endo :: s a a }
-  deriving (Typeable)
 
 instance Category s => Semigroup (Endo s a) where
     Endo f <> Endo g = Endo (f . g)
diff --git a/Data/Morphism/Iso.hs b/Data/Morphism/Iso.hs
--- a/Data/Morphism/Iso.hs
+++ b/Data/Morphism/Iso.hs
@@ -1,13 +1,30 @@
 module Data.Morphism.Iso where
 
+import qualified Algebra as A
+import Control.Categorical.Functor
+import Control.Category.Dual
 import Control.Category.Groupoid
 
 data Iso s a b = Iso (s a b) (s b a)
-  deriving (Typeable)
 
+instance (Semigroup (s a b), Semigroup (s b a)) => Semigroup (Iso s a b) where
+    Iso f f' <> Iso g g' = Iso (f <> g) (f' <> g')
+
+instance (Monoid (s a b), Monoid (s b a)) => Monoid (Iso s a b) where
+    mempty = Iso mempty mempty
+
+instance (Group (s a b), Group (s b a)) => Group (Iso s a b) where
+    invert (Iso f f') = Iso (A.invert f) (A.invert f')
+
 instance Category s => Category (Iso s) where
     id = Iso id id
     Iso f f' . Iso g g' = Iso (f . g) (g' . f')
 
 instance Category s => Groupoid (Iso s) where
     invert (Iso f f') = Iso f' f
+
+instance Functor s t f => Functor (Iso s) t f where
+    map (Iso f _) = map f
+
+instance Functor s t f => Functor (Iso s) (Dual t) f where
+    map (Iso _ f') = Dual (map f')
diff --git a/Prelude.hs b/Prelude.hs
--- a/Prelude.hs
+++ b/Prelude.hs
@@ -1,14 +1,9 @@
 module Prelude (module Control.Category,
-                module Data.Data,
                 module Data.Either,
-                module Data.Type.Equality,
-                module Data.Typeable,
-                Semigroup (..), Monoid (..)) where
+                Semigroup (..), Monoid (..), Group) where
 
+import Algebra (Group)
 import Control.Category
-import Data.Data
 import Data.Either
 import Data.Monoid (Monoid (..))
 import Data.Semigroup (Semigroup (..))
-import Data.Type.Equality
-import Data.Typeable
diff --git a/category.cabal b/category.cabal
--- a/category.cabal
+++ b/category.cabal
@@ -1,5 +1,5 @@
 name:                category
-version:             0.1.1.0
+version:             0.1.2.0
 synopsis:            Categorical types and classes
 -- description:         
 license:             BSD3
@@ -7,12 +7,14 @@
 author:              M Farkas-Dyck
 maintainer:          strake888@gmail.com
 -- copyright:           
-category:            Control
+category:            Control, Math
 build-type:          Simple
 cabal-version:       >=1.10
 
 library
-  exposed-modules:     Control.Category.Dual
+  exposed-modules:     Control.Categorical.Functor
+                     , Control.Category.Const2
+                     , Control.Category.Dual
                      , Control.Category.Groupoid
                      , Data.Morphism.Endo
                      , Data.Morphism.Iso
@@ -20,7 +22,12 @@
   build-depends:       base >=4.10 && <5
                      , alg >=0.2 && <0.3
   default-language:    Haskell2010
-  default-extensions:  LambdaCase
+  default-extensions:  UnicodeSyntax
+                     , LambdaCase
                      , PolyKinds
-                     , DeriveDataTypeable
+                     , ConstraintKinds
+                     , MultiParamTypeClasses
+                     , FlexibleContexts
+                     , FlexibleInstances
+                     , GeneralizedNewtypeDeriving
   ghc-options:         -Wall
