diff --git a/lawful-conversions.cabal b/lawful-conversions.cabal
--- a/lawful-conversions.cabal
+++ b/lawful-conversions.cabal
@@ -1,6 +1,6 @@
 cabal-version: 3.0
 name: lawful-conversions
-version: 0.1.6
+version: 0.1.6.1
 synopsis: Lawful typeclasses for bidirectional conversion between types
 category: Conversion
 homepage: https://github.com/nikita-volkov/lawful-conversions
@@ -52,11 +52,17 @@
 
   = Prior work and acknowledgements
 
-  This library is a direct successor of the "[isomorphism-class](https://hackage.haskell.org/package/isomorphism-class)" library, expanding upon the patterns discovered there. It also shares some ideas with "[control-iso](https://hackage.haskell.org/package/control-iso)" and "[type-iso](https://hackage.haskell.org/package/type-iso)".
+  This library is an offspring of the "[isomorphism-class](https://hackage.haskell.org/package/isomorphism-class)" library, expanding upon the patterns discovered there. Both libraries are maintained letting their designs compete.
 
+  Some ideas and concepts are also shared with the following libraries:
+
+  - [control-iso](https://hackage.haskell.org/package/control-iso)
+  - [type-iso](https://hackage.haskell.org/package/type-iso)
+  - [injections](https://hackage.haskell.org/package/injections)
+
 source-repository head
   type: git
-  location: git://github.com/nikita-volkov/lawful-conversions.git
+  location: https://github.com/nikita-volkov/lawful-conversions
 
 common base
   default-language: Haskell2010
@@ -78,9 +84,6 @@
   exposed-modules: LawfulConversions
   other-modules:
     LawfulConversions.Classes
-    LawfulConversions.Classes.Is
-    LawfulConversions.Classes.IsMany
-    LawfulConversions.Classes.IsSome
     LawfulConversions.Optics
     LawfulConversions.Prelude
     LawfulConversions.Properties
diff --git a/src/library/LawfulConversions/Classes.hs b/src/library/LawfulConversions/Classes.hs
--- a/src/library/LawfulConversions/Classes.hs
+++ b/src/library/LawfulConversions/Classes.hs
@@ -1,6 +1,145 @@
-module LawfulConversions.Classes
-  ( module LawfulConversions.Classes.Is,
-  )
-where
+module LawfulConversions.Classes where
 
-import LawfulConversions.Classes.Is
+import LawfulConversions.Prelude
+
+-- |
+-- Evidence that all values of type @b@ form a subset of all values of type @a@.
+--
+-- [From Wikipedia](https://en.wikipedia.org/wiki/Subset):
+--
+-- In mathematics, a set A is a subset of a set B if all elements of A are also elements of B; B is then a superset of A. It is possible for A and B to be equal; if they are unequal, then A is a proper subset of B. The relationship of one set being a subset of another is called inclusion (or sometimes containment). A is a subset of B may also be expressed as B includes (or contains) A or A is included (or contained) in B. A k-subset is a subset with k elements.
+--
+-- === Laws
+--
+-- ==== 'to' is [injective](https://en.wikipedia.org/wiki/Injective_function)
+--
+-- For every two values of type @b@ that are not equal converting with 'to' produces values that are not equal as well:
+--
+-- > \(b1, b2) -> b1 == b2 || to @a b1 /= to @a b2
+--
+-- ==== 'maybeFrom' is a [partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'
+--
+-- For all values of @b@ converting to @a@ and then attempting to convert back to @b@ always succeeds and produces a value that is equal to the original:
+--
+-- > \b -> maybeFrom (to @a b) == Just b
+--
+-- === Testing
+--
+-- For testing whether your instances conform to these laws use 'LawfulConversions.isSomeProperties'.
+class IsSome a b where
+  -- |
+  -- Convert a value of a subset type to a superset type.
+  to :: b -> a
+
+  -- |
+  -- [Partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'.
+  maybeFrom :: a -> Maybe b
+
+  -- |
+  -- Requires the presence of 'IsSome' in reverse direction.
+  default maybeFrom :: (IsSome b a) => a -> Maybe b
+  maybeFrom = Just . to
+
+-- | Every type is isomorphic to itself.
+instance IsSome a a where
+  to = id
+  maybeFrom = Just . id
+
+-- | The empty set has no elements, and therefore is vacuously a subset of any set.
+instance IsSome a Void where
+  to = absurd
+  maybeFrom = const Nothing
+
+-- |
+-- Lossy or canonicalizing conversion.
+-- Captures mappings from multiple alternative inputs into one output.
+--
+-- E.g.,
+--
+-- - `ByteString` can be decoded into `Text` with UTF-8 leniently, replacing the invalid chars with a default char.
+--
+-- - `String` has a wider range of supported chars than `Text`, so some chars get replaced too.
+--
+-- === Laws
+--
+-- ==== 'from' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'
+--
+-- > \b -> b == from (to @a b)
+--
+-- === Testing
+--
+-- For testing whether your instances conform to these laws use 'LawfulConversions.isManyProperties'.
+class (IsSome a b) => IsMany a b where
+  -- |
+  -- Possibly lossy inverse of 'to'.
+  -- [Surjection](https://en.wikipedia.org/wiki/Surjective_function) from @a@ to @b@.
+  --
+  -- Particularly useful in combination with the @TypeApplications@ extension,
+  -- where it allows to specify the input type, e.g.:
+  --
+  -- > fromText :: IsMany Text b => Text -> b
+  -- > fromText = from @Text
+  --
+  -- The first type application of the 'to' function on the other hand specifies
+  -- the output data type.
+  from :: a -> b
+
+  -- |
+  -- Requires the presence of 'IsSome' in reverse direction.
+  default from :: (IsSome b a) => a -> b
+  from = to
+
+instance IsMany a a
+
+-- | Bidirectional conversion between two types with no loss of information.
+--
+-- The bidirectionality is encoded via a recursive dependency with arguments
+-- flipped.
+--
+-- You can read the signature @Is a b@ as \"/B/ is /A/\".
+--
+-- === Laws
+--
+-- ==== 'from' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'
+--
+-- For all values of /b/ converting from /b/ to /a/ and then converting from /a/ to /b/ produces the original value:
+--
+-- > \b -> b == from (to @a b)
+--
+-- ==== 'to' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'from'
+--
+-- For all values of /a/ converting from /a/ to /b/ and then converting from /b/ to /a/ produces the original value:
+--
+-- > \a -> a == to (from @a @b a)
+--
+-- === Testing
+--
+-- For testing whether your instances conform to these laws use 'LawfulConversions.isProperties'.
+--
+-- === Instance Definition
+--
+-- For each pair of isomorphic types (/A/ and /B/) the compiler will require you to define six instances, namely: @Is A B@ and @Is B A@, @IsMany A B@ and @IsMany B A@, @IsSome A B@ and @IsSome B A@.
+--
+-- Instances of @Is@ do not define any functions and serve merely as a statement that the laws are satisfied.
+--
+-- ==== Example: Lazy Text and Text
+--
+-- @
+-- instance IsSome "Data.Text.Lazy.LazyText" "Data.Text.Text" where
+--   to = LazyText.'Data.Text.Lazy.fromStrict'
+--
+-- instance IsSome "Data.Text.Text" "Data.Text.Lazy.LazyText" where
+--   to = LazyText.'Data.Text.Lazy.toStrict'
+--
+-- instance IsMany "Data.Text.Lazy.LazyText" "Data.Text.Text"
+--
+-- instance IsMany "Data.Text.Text" "Data.Text.Lazy.LazyText"
+--
+-- instance Is "Data.Text.Lazy.LazyText" "Data.Text.Text"
+--
+-- instance Is "Data.Text.Text" "Data.Text.Lazy.LazyText"
+-- @
+class (IsMany a b, Is b a) => Is a b
+
+-- | Any type is isomorphic to itself.
+instance Is a a
diff --git a/src/library/LawfulConversions/Classes/Is.hs b/src/library/LawfulConversions/Classes/Is.hs
deleted file mode 100644
--- a/src/library/LawfulConversions/Classes/Is.hs
+++ /dev/null
@@ -1,60 +0,0 @@
-module LawfulConversions.Classes.Is
-  ( module LawfulConversions.Classes.Is,
-    module LawfulConversions.Classes.IsMany,
-  )
-where
-
-import LawfulConversions.Classes.IsMany
-
--- | Bidirectional conversion between two types with no loss of information.
---
--- The bidirectionality is encoded via a recursive dependency with arguments
--- flipped.
---
--- You can read the signature @Is a b@ as \"/B/ is /A/\".
---
--- === Laws
---
--- ==== 'from' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'
---
--- For all values of /b/ converting from /b/ to /a/ and then converting from /a/ to /b/ produces the original value:
---
--- > \b -> b == from (to @a b)
---
--- ==== 'to' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'from'
---
--- For all values of /a/ converting from /a/ to /b/ and then converting from /b/ to /a/ produces the original value:
---
--- > \a -> a == to (from @a @b a)
---
--- === Testing
---
--- For testing whether your instances conform to these laws use 'LawfulConversions.isProperties'.
---
--- === Instance Definition
---
--- For each pair of isomorphic types (/A/ and /B/) the compiler will require you to define six instances, namely: @Is A B@ and @Is B A@, @IsMany A B@ and @IsMany B A@, @IsSome A B@ and @IsSome B A@.
---
--- Instances of @Is@ do not define any functions and serve merely as a statement that the laws are satisfied.
---
--- ==== Example: Lazy Text and Text
---
--- @
--- instance IsSome "Data.Text.Lazy.LazyText" "Data.Text.Text" where
---   to = LazyText.'Data.Text.Lazy.fromStrict'
---
--- instance IsSome "Data.Text.Text" "Data.Text.Lazy.LazyText" where
---   to = LazyText.'Data.Text.Lazy.toStrict'
---
--- instance IsMany "Data.Text.Lazy.LazyText" "Data.Text.Text"
---
--- instance IsMany "Data.Text.Text" "Data.Text.Lazy.LazyText"
---
--- instance Is "Data.Text.Lazy.LazyText" "Data.Text.Text"
---
--- instance Is "Data.Text.Text" "Data.Text.Lazy.LazyText"
--- @
-class (IsMany a b, Is b a) => Is a b
-
--- | Any type is isomorphic to itself.
-instance Is a a
diff --git a/src/library/LawfulConversions/Classes/IsMany.hs b/src/library/LawfulConversions/Classes/IsMany.hs
deleted file mode 100644
--- a/src/library/LawfulConversions/Classes/IsMany.hs
+++ /dev/null
@@ -1,48 +0,0 @@
-module LawfulConversions.Classes.IsMany
-  ( module LawfulConversions.Classes.IsMany,
-    module LawfulConversions.Classes.IsSome,
-  )
-where
-
-import LawfulConversions.Classes.IsSome
-
--- |
--- Lossy or canonicalizing conversion.
--- Captures mappings from multiple alternative inputs into one output.
---
--- E.g.,
---
--- - `ByteString` can be decoded into `Text` with UTF-8 leniently, replacing the invalid chars with a default char.
---
--- - `String` has a wider range of supported chars than `Text`, so some chars get replaced too.
---
--- === Laws
---
--- ==== 'from' is an [inverse](https://en.wikipedia.org/wiki/Inverse_function) of 'to'
---
--- > \b -> b == from (to @a b)
---
--- === Testing
---
--- For testing whether your instances conform to these laws use 'LawfulConversions.isManyProperties'.
-class (IsSome a b) => IsMany a b where
-  -- |
-  -- Possibly lossy inverse of 'to'.
-  -- [Surjection](https://en.wikipedia.org/wiki/Surjective_function) from @a@ to @b@.
-  --
-  -- Particularly useful in combination with the @TypeApplications@ extension,
-  -- where it allows to specify the input type, e.g.:
-  --
-  -- > fromText :: IsMany Text b => Text -> b
-  -- > fromText = from @Text
-  --
-  -- The first type application of the 'to' function on the other hand specifies
-  -- the output data type.
-  from :: a -> b
-
-  -- |
-  -- Requires the presence of 'IsSome' in reverse direction.
-  default from :: (IsSome b a) => a -> b
-  from = to
-
-instance IsMany a a
diff --git a/src/library/LawfulConversions/Classes/IsSome.hs b/src/library/LawfulConversions/Classes/IsSome.hs
deleted file mode 100644
--- a/src/library/LawfulConversions/Classes/IsSome.hs
+++ /dev/null
@@ -1,51 +0,0 @@
-module LawfulConversions.Classes.IsSome where
-
-import LawfulConversions.Prelude
-
--- |
--- Evidence that all values of type @b@ form a subset of all values of type @a@.
---
--- [From Wikipedia](https://en.wikipedia.org/wiki/Subset):
---
--- In mathematics, a set A is a subset of a set B if all elements of A are also elements of B; B is then a superset of A. It is possible for A and B to be equal; if they are unequal, then A is a proper subset of B. The relationship of one set being a subset of another is called inclusion (or sometimes containment). A is a subset of B may also be expressed as B includes (or contains) A or A is included (or contained) in B. A k-subset is a subset with k elements.
---
--- === Laws
---
--- ==== 'to' is [injective](https://en.wikipedia.org/wiki/Injective_function)
---
--- For every two values of type @b@ that are not equal converting with 'to' produces values that are not equal as well:
---
--- > \(b1, b2) -> b1 == b2 || to @a b1 /= to @a b2
---
--- ==== 'maybeFrom' is a [partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'
---
--- For all values of @b@ converting to @a@ and then attempting to convert back to @b@ always succeeds and produces a value that is equal to the original:
---
--- > \b -> maybeFrom (to @a b) == Just b
---
--- === Testing
---
--- For testing whether your instances conform to these laws use 'LawfulConversions.isSomeProperties'.
-class IsSome a b where
-  -- |
-  -- Convert a value of a subset type to a superset type.
-  to :: b -> a
-
-  -- |
-  -- [Partial inverse](https://en.wikipedia.org/wiki/Inverse_function#Partial_inverses) of 'to'.
-  maybeFrom :: a -> Maybe b
-
-  -- |
-  -- Requires the presence of 'IsSome' in reverse direction.
-  default maybeFrom :: (IsSome b a) => a -> Maybe b
-  maybeFrom = Just . to
-
--- | Every type is isomorphic to itself.
-instance IsSome a a where
-  to = id
-  maybeFrom = Just . id
-
--- | The empty set has no elements, and therefore is vacuously a subset of any set.
-instance IsSome a Void where
-  to = absurd
-  maybeFrom = const Nothing
