diff --git a/LICENSE.markdown b/LICENSE.markdown
new file mode 100644
--- /dev/null
+++ b/LICENSE.markdown
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 Taylor Fausak
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/LICENSE.txt b/LICENSE.txt
deleted file mode 100644
--- a/LICENSE.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-Copyright 2021 Taylor Fausak
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
-REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
-INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
-LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
-OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS SOFTWARE.
diff --git a/source/ghc-8.10/Witch/Lift.hs b/source/ghc-8.10/Witch/Lift.hs
new file mode 100644
--- /dev/null
+++ b/source/ghc-8.10/Witch/Lift.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE ExplicitForAll #-}
+
+module Witch.Lift where
+
+import qualified Data.Typeable as Typeable
+import qualified Language.Haskell.TH.Syntax as TH
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.Utility as Utility
+
+-- | This is like 'Utility.unsafeFrom' except that it works at compile time
+-- rather than runtime.
+--
+-- > -- Avoid this:
+-- > unsafeFrom @s "some literal"
+-- >
+-- > -- Prefer this:
+-- > $$(liftedFrom @s "some literal")
+liftedFrom
+  :: forall source target
+   . ( TryFrom.TryFrom source target
+     , TH.Lift target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     )
+  => source
+  -> TH.Q (TH.TExp target)
+liftedFrom = TH.liftTyped . Utility.unsafeFrom
+
+-- | This is like 'Utility.unsafeInto' except that it works at compile time
+-- rather than runtime.
+--
+-- > -- Avoid this:
+-- > unsafeInto @t "some literal"
+-- >
+-- > -- Prefer this:
+-- > $$(liftedInto @t "some literal")
+liftedInto
+  :: forall target source
+   . ( TryFrom.TryFrom source target
+     , TH.Lift target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     )
+  => source
+  -> TH.Q (TH.TExp target)
+liftedInto = liftedFrom
diff --git a/source/ghc-8.8/Witch/Lift.hs b/source/ghc-8.8/Witch/Lift.hs
new file mode 100644
--- /dev/null
+++ b/source/ghc-8.8/Witch/Lift.hs
@@ -0,0 +1,48 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Witch.Lift where
+
+import qualified Data.Typeable as Typeable
+import qualified Language.Haskell.TH.Syntax as TH
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.Utility as Utility
+
+-- | This is like 'Utility.unsafeFrom' except that it works at compile time
+-- rather than runtime.
+--
+-- > -- Avoid this:
+-- > unsafeFrom @s "some literal"
+-- >
+-- > -- Prefer this:
+-- > $$(liftedFrom @s "some literal")
+liftedFrom
+  :: forall source target
+   . ( TryFrom.TryFrom source target
+     , TH.Lift target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     )
+  => source
+  -> TH.Q (TH.TExp target)
+liftedFrom s = TH.unsafeTExpCoerce $ TH.lift (Utility.unsafeFrom s :: target)
+
+-- | This is like 'Utility.unsafeInto' except that it works at compile time
+-- rather than runtime.
+--
+-- > -- Avoid this:
+-- > unsafeInto @t "some literal"
+-- >
+-- > -- Prefer this:
+-- > $$(liftedInto @t "some literal")
+liftedInto
+  :: forall target source
+   . ( TryFrom.TryFrom source target
+     , TH.Lift target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     )
+  => source
+  -> TH.Q (TH.TExp target)
+liftedInto = liftedFrom
diff --git a/source/ghc-9.0/Witch/Lift.hs b/source/ghc-9.0/Witch/Lift.hs
new file mode 100644
--- /dev/null
+++ b/source/ghc-9.0/Witch/Lift.hs
@@ -0,0 +1,50 @@
+{-# LANGUAGE ExplicitForAll #-}
+
+module Witch.Lift where
+
+import qualified Data.Typeable as Typeable
+import qualified Language.Haskell.TH.Syntax as TH
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.Utility as Utility
+
+-- | This is like 'Utility.unsafeFrom' except that it works at compile time
+-- rather than runtime.
+--
+-- > -- Avoid this:
+-- > unsafeFrom @s "some literal"
+-- >
+-- > -- Prefer this:
+-- > $$(liftedFrom @s "some literal")
+liftedFrom
+  :: forall source target m
+   . ( TryFrom.TryFrom source target
+     , TH.Lift target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     , TH.Quote m
+     )
+  => source
+  -> TH.Code m target
+liftedFrom = TH.liftTyped . Utility.unsafeFrom
+
+-- | This is like 'Utility.unsafeInto' except that it works at compile time
+-- rather than runtime.
+--
+-- > -- Avoid this:
+-- > unsafeInto @t "some literal"
+-- >
+-- > -- Prefer this:
+-- > $$(liftedInto @t "some literal")
+liftedInto
+  :: forall target source m
+   . ( TryFrom.TryFrom source target
+     , TH.Lift target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     , TH.Quote m
+     )
+  => source
+  -> TH.Code m target
+liftedInto = liftedFrom
diff --git a/source/library/Witch.hs b/source/library/Witch.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch.hs
@@ -0,0 +1,258 @@
+-- | The Witch package is a library that allows you to confidently convert
+-- values between various types. This module exports everything you need to
+-- perform conversions or define your own. It is designed to be imported
+-- unqualified, so getting started is as easy as:
+--
+-- >>> import Witch
+--
+-- In typical usage, the functions that you will use most often are
+-- 'Witch.Utility.into' for conversions that always succeed and
+-- 'Witch.Utility.tryInto' for conversions that sometimes fail.
+module Witch
+  ( -- * Type classes
+
+  -- ** From
+    Witch.From.From(from)
+  , Witch.Utility.into
+
+  -- ** TryFrom
+  , Witch.TryFrom.TryFrom(tryFrom)
+  , Witch.Utility.tryInto
+
+  -- * Data types
+  , Witch.TryFromException.TryFromException(..)
+
+  -- * Utilities
+  , Witch.Utility.as
+  , Witch.Utility.over
+  , Witch.Utility.via
+  , Witch.Utility.tryVia
+  , Witch.Utility.maybeTryFrom
+  , Witch.Utility.eitherTryFrom
+
+  -- ** Unsafe
+  -- | These functions should only be used in two circumstances: When you know
+  -- a conversion is safe even though you can't prove it to the compiler, and
+  -- when you're alright with your program crashing if the conversion fails.
+  -- In all other cases you should prefer the normal conversion functions like
+  -- 'Witch.TryFrom.tryFrom'. And if you're converting a literal value,
+  -- consider using the Template Haskell conversion functions like
+  -- 'Witch.Lift.liftedFrom'.
+  , Witch.Utility.unsafeFrom
+  , Witch.Utility.unsafeInto
+
+  -- ** Template Haskell
+  -- | This library uses /typed/ Template Haskell, which may be a little
+  -- different than what you're used to. Normally Template Haskell uses the
+  -- @$(...)@ syntax for splicing in things to run at compile time. The typed
+  -- variant uses the @$$(...)@ syntax for splices, doubling up on the dollar
+  -- signs. Other than that, using typed Template Haskell should be pretty
+  -- much the same as using regular Template Haskell.
+  , Witch.Lift.liftedFrom
+  , Witch.Lift.liftedInto
+
+  -- * Notes
+
+  -- ** Motivation
+  -- | Haskell provides many ways to convert between common types, and core
+  -- libraries add even more. It can be challenging to know which function to
+  -- use when converting from some source type @a@ to some target type @b@. It
+  -- can be even harder to know if that conversion is safe or if there are any
+  -- pitfalls to watch out for.
+  --
+  -- This library tries to address that problem by providing a common
+  -- interface for converting between types. The 'Witch.From.From' type class
+  -- is for conversions that cannot fail, and the 'Witch.TryFrom.TryFrom' type
+  -- class is for conversions that can fail. These type classes are inspired
+  -- by the [@From@](https://doc.rust-lang.org/std/convert/trait.From.html)
+  -- trait in Rust.
+
+  -- ** Type applications
+  -- | Although you can use this library without the [@TypeApplications@](https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/exts/type_applications.html)
+  -- language extension, the extension is strongly recommended. Since most
+  -- functions provided by this library are polymorphic in at least one type
+  -- variable, it's easy to use them in a situation that would be ambiguous.
+  -- Normally you could resolve the ambiguity with an explicit type signature,
+  -- but type applications are much more ergonomic. For example:
+  --
+  -- > -- Avoid this:
+  -- > f . (from :: Int8 -> Int16) . g
+  -- >
+  -- > -- Prefer this:
+  -- > f . from @Int8 @Int16 . g
+  --
+  -- Most functions in this library have two versions with their type
+  -- variables in opposite orders. That's because usually one side of the
+  -- conversion or the other already has its type inferred by context. In
+  -- those situations it makes sense to only provide one type argument.
+  --
+  -- > -- Avoid this: (assuming f :: Int16 -> ...)
+  -- > f $ from @Int8 @Int16 0
+  -- >
+  -- > -- Prefer this:
+  -- > f $ from @Int8 0
+  --
+  -- > -- Avoid this: (assuming x :: Int8)
+  -- > g $ from @Int8 @Int16 x
+  -- >
+  -- > -- Prefer this:
+  -- > g $ into @Int16 x
+
+  -- ** Alternatives
+  -- | Many Haskell libraries already provide similar functionality. How is
+  -- this library different?
+  --
+  -- - [@Coercible@](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Coerce.html#t:Coercible):
+  --   This type class is solved by the compiler, but it only works for types
+  --   that have the same runtime representation. This is very convenient for
+  --   @newtype@s, but it does not work for converting between arbitrary types
+  --   like @Int8@ and @Int16@.
+  --
+  -- - [@Convertible@](https://hackage.haskell.org/package/convertible-1.1.1.0/docs/Data-Convertible-Base.html#t:Convertible):
+  --   This popular conversion type class is similar to what this library
+  --   provides. The main difference is that it does not differentiate between
+  --   conversions that can fail and those that cannot.
+  --
+  -- - [@From@](https://hackage.haskell.org/package/basement-0.0.11/docs/Basement-From.html#t:From):
+  --   This type class is almost identical to what this library provides.
+  --   Unfortunately it is part of the @basement@ package, which is an
+  --   alternative standard library that some people may not want to depend
+  --   on.
+  --
+  -- - [@Inj@](https://hackage.haskell.org/package/inj-1.0/docs/Inj.html#t:Inj):
+  --   This type class requires instances to be an injection, which means that
+  --   no two input values should map to the same output. That restriction
+  --   prohibits many useful instances. Also many instances throw impure
+  --   exceptions.
+  --
+  -- In addition to those general-purpose type classes, there are many
+  -- alternatives for more specific conversions. How does this library compare
+  -- to those?
+  --
+  -- - Monomorphic conversion functions like [@Data.Text.pack@](https://hackage.haskell.org/package/text-1.2.4.1/docs/Data-Text.html#v:pack)
+  --   are explicit but not necessarily convenient. It can be tedious to
+  --   manage the imports necessary to use the functions. And if you want to
+  --   put them in a custom prelude, you will have to come up with your own
+  --   names.
+  --
+  -- - Polymorphic conversion methods like 'toEnum' are more convenient but
+  --   may have unwanted semantics or runtime behavior. For example the 'Enum'
+  --   type class is more or less tied to the 'Int' data type and frequently
+  --   throws impure exceptions.
+  --
+  -- - Polymorphic conversion functions like 'fromIntegral' are very
+  --   convenient. Unfortunately it can be challenging to know which types
+  --   have the instances necessary to make the conversion possible. And even
+  --   if the conversion is possible, is it safe? For example converting a
+  --   negative 'Int' into a 'Word' will overflow, which may be surprising.
+
+  -- ** Instances
+  -- | When should you add a 'Witch.From.From' (or 'Witch.TryFrom.TryFrom')
+  -- instance for some pair of types? This is a surprisingly tricky question
+  -- to answer precisely. Instances are driven more by guidelines than rules.
+  --
+  -- - Conversions must not throw impure exceptions. This means no 'undefined'
+  --   or anything equivalent to it.
+  --
+  -- - Conversions should be unambiguous. If there are multiple reasonable
+  --   ways to convert from @a@ to @b@, then you probably should not add a
+  --   'Witch.From.From' instance for them.
+  --
+  -- - Conversions should be lossless. If you have @From a b@ then no two @a@
+  --   values should be converted to the same @b@ value.
+  --
+  --     - Some conversions necessarily lose information, like converting from
+  --       a list into a set.
+  --
+  -- - If you have both @From a b@ and @From b a@, then
+  --   @from \@b \@a . from \@a \@b@ should be the same as 'id'. In other
+  --   words, @a@ and @b@ are isomorphic.
+  --
+  --     - This often true, but not always. For example, converting a list
+  --       into a set will remove duplicates. And then converting back into a
+  --       list will put the elements in ascending order.
+  --
+  -- - If you have both @From a b@ and @From b c@, then you could also have
+  --   @From a c@ and it should be the same as @from \@b \@c . from \@a \@b@.
+  --   In other words, @From@ is transitive.
+  --
+  --     - This is not always true. For example an @Int8@ may be represented
+  --       as a number in JSON, whereas an @Int64@ might be represented as a
+  --       string. That means @into \@JSON (into \@Int64 int8)@ would not be
+  --       the same as @into \@JSON int8@.
+  --
+  -- - You should not have both a @From@ instance and a @TryFrom@ instance for
+  --   the same pair of types.
+  --
+  -- - If you have a @From@ or @TryFrom@ instance for a pair of types, then
+  --   you should probably have a @From@ or @TryFrom@ instance for the same
+  --   pair of types but in the opposite direction. In other words if you have
+  --   @From a b@ then you should have @From b a@ or @TryFrom b a@.
+  --
+  -- In general if @s@ /is/ a @t@, then you should add a 'Witch.From.From'
+  -- instance for it. But if @s@ merely /can be/ a @t@, then you could add a
+  -- 'Witch.TryFrom.TryFrom' instance for it. And if it is technically
+  -- possible to convert from @s@ to @t@ but there are a lot of caveats, you
+  -- probably should not write any instances at all.
+
+  -- ** Laws
+  -- | As the previous section notes, there aren't any cut and dried laws for
+  -- the @From@ and @TryFrom@ type classes. However it can be useful to
+  -- consider the following equations for guiding instances:
+  --
+  -- > -- same strictness
+  -- > seq (from @a @b x) y = seq x y
+  -- > seq (tryFrom @a @b x) y = seq x y
+  --
+  -- > -- round trip
+  -- > from @b @a (from @a @b x) = x
+  --
+  -- > -- transitive
+  -- > from @b @c (from @a @b x) = from @a @c x
+  -- > tryFrom @b @a (from @a @b x) = Right x
+  -- > if isRight (tryFrom @a @b x) then
+  -- >   fmap (from @b @a) (tryFrom @a @b x) = Right x
+  -- > if isRight (tryFrom @a @b x) then do
+  -- >   fmap (tryFrom @b @a) (tryFrom @a @b x) = Right (Right x)
+
+  -- ** Integral types
+  -- | There are a lot of types that represent various different ranges of
+  -- integers, and Witch may not provide the instances you want. In particular
+  -- it does not provide a total way to convert from an @Int32@ into an @Int@.
+  -- Why is that?
+  --
+  -- The Haskell Language Report only demands that @Int@s have at least 30
+  -- bits of precision. That means a reasonable Haskell implementation could
+  -- have an @Int@ type that's smaller than the @Int32@ type.
+  --
+  -- However in practice everyone uses the same Haskell implementation: GHC.
+  -- And with GHC the @Int@ type always has 32 bits of precision, even on
+  -- 32-bit architectures. So for almost everybody, it's probably safe to use
+  -- @unsafeFrom \@Int32 \@Int@. Similarly most software these days runs on
+  -- machines with 64-bit architectures. That means it's also probably safe
+  -- for you to use @unsafeFrom \@Int64 \@Int@.
+  --
+  -- All of the above also applies for @Word@, @Word32@, and @Word64@.
+
+  -- ** Downsides
+  -- | As the author of this library, I obviously think that everyone should
+  -- use it because it's the greatest thing since sliced bread. But nothing is
+  -- perfect, so what are some downsides to this library?
+  --
+  -- - More specific type classes are often better. For example, @IsString s@
+  --   is more useful that @From String s@. The former says that the type @s@
+  --   is the same as a string literal, but the latter just says you can
+  --   produce a value of type @s@ when given a string.
+  --
+  -- - The @From@ type class works great for specific pairs of types, but can
+  --   get confusing when it's polymorphic. For example if you have some
+  --   function with a @From s t@ constraint, that doesn't really tell you
+  --   anything about what it's doing.
+  ) where
+
+import qualified Witch.From
+import Witch.Instances ()
+import qualified Witch.Lift
+import qualified Witch.TryFrom
+import qualified Witch.TryFromException
+import qualified Witch.Utility
diff --git a/source/library/Witch/From.hs b/source/library/Witch/From.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch/From.hs
@@ -0,0 +1,36 @@
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module Witch.From where
+
+import qualified Data.Coerce as Coerce
+
+-- | This type class is for converting values from some @source@ type into
+-- some other @target@ type. The constraint @'From' source target@ means that
+-- you can convert from a value of type @source@ into a value of type
+-- @target@.
+--
+-- This type class is for conversions that always succeed. If your conversion
+-- sometimes fails, consider implementing @TryFrom@ instead.
+class From source target where
+  -- | This method implements the conversion of a value between types. At call
+  -- sites you may prefer to use @into@ instead.
+  --
+  -- > -- Avoid this:
+  -- > from (x :: s)
+  -- >
+  -- > -- Prefer this:
+  -- > from @s x
+  --
+  -- The default implementation of this method simply calls 'Coerce.coerce',
+  -- which works for types that have the same runtime representation. This
+  -- means that for @newtype@s you do not need to implement this method at
+  -- all. For example:
+  --
+  -- >>> newtype Name = Name String
+  -- >>> instance From Name String
+  -- >>> instance From String Name
+  from :: source -> target
+
+  default from :: Coerce.Coercible source target => source -> target
+  from = Coerce.coerce
diff --git a/source/library/Witch/Instances.hs b/source/library/Witch/Instances.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch/Instances.hs
@@ -0,0 +1,1293 @@
+{-# OPTIONS_GHC -Wno-orphans #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TypeApplications #-}
+
+module Witch.Instances where
+
+import qualified Control.Exception as Exception
+import qualified Data.Bits as Bits
+import qualified Data.ByteString as ByteString
+import qualified Data.ByteString.Lazy as LazyByteString
+import qualified Data.ByteString.Short as ShortByteString
+import qualified Data.Complex as Complex
+import qualified Data.Fixed as Fixed
+import qualified Data.Foldable as Foldable
+import qualified Data.Int as Int
+import qualified Data.IntMap as IntMap
+import qualified Data.IntSet as IntSet
+import qualified Data.List as List
+import qualified Data.List.NonEmpty as NonEmpty
+import qualified Data.Map as Map
+import qualified Data.Ratio as Ratio
+import qualified Data.Sequence as Seq
+import qualified Data.Set as Set
+import qualified Data.Text as Text
+import qualified Data.Text.Encoding as Text
+import qualified Data.Text.Lazy as LazyText
+import qualified Data.Text.Lazy.Encoding as LazyText
+import qualified Data.Time as Time
+import qualified Data.Time.Clock.POSIX as Time
+import qualified Data.Time.Clock.System as Time
+import qualified Data.Time.Clock.TAI as Time
+import qualified Data.Word as Word
+import qualified GHC.Float as Float
+import qualified Numeric
+import qualified Numeric.Natural as Natural
+import qualified Witch.From as From
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.TryFromException as TryFromException
+import qualified Witch.Utility as Utility
+
+-- | Uses 'id'.
+instance From.From a a where
+  from = id
+
+-- Int8
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Int.Int16 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Int.Int32 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Int where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Integer where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int8 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int8 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int8 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int8 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int8 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral' when the input is not negative.
+instance TryFrom.TryFrom Int.Int8 Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Float where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int8 Double where
+  from = fromIntegral
+
+-- Int16
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int16 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int16 Int.Int32 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int16 Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int16 Int where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int16 Integer where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int16 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int16 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int16 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int16 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int16 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral' when the input is not negative.
+instance TryFrom.TryFrom Int.Int16 Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int16 Float where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int16 Double where
+  from = fromIntegral
+
+-- Int32
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int32 Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int32 Integer where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int32 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral' when the input is not negative.
+instance TryFrom.TryFrom Int.Int32 Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
+
+-- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
+-- inclusive.
+instance TryFrom.TryFrom Int.Int32 Float where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
+    then Left Exception.Underflow
+    else if s > maxFloat
+      then Left Exception.Overflow
+      else Right $ fromIntegral s
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int32 Double where
+  from = fromIntegral
+
+-- Int64
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Int.Int64 Integer where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int.Int64 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral' when the input is not negative.
+instance TryFrom.TryFrom Int.Int64 Natural.Natural where
+  -- This should use @eitherTryFrom fromNonNegativeIntegral@, but that causes
+  -- a bug in GHC 9.0.1.
+  -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html
+  tryFrom =
+    Utility.eitherTryFrom $ \s -> TryFrom.tryFrom (From.from s :: Integer)
+
+-- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
+-- inclusive.
+instance TryFrom.TryFrom Int.Int64 Float where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
+    then Left Exception.Underflow
+    else if s > maxFloat
+      then Left Exception.Overflow
+      else Right $ fromIntegral s
+
+-- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
+-- 9,007,199,254,740,991 inclusive.
+instance TryFrom.TryFrom Int.Int64 Double where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxDouble
+    then Left Exception.Underflow
+    else if s > maxDouble
+      then Left Exception.Overflow
+      else Right $ fromIntegral s
+
+-- Int
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Int Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Int Integer where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Int Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral' when the input is not negative.
+instance TryFrom.TryFrom Int Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
+
+-- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
+-- inclusive.
+instance TryFrom.TryFrom Int Float where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
+    then Left Exception.Underflow
+    else if s > maxFloat
+      then Left Exception.Overflow
+      else Right $ fromIntegral s
+
+-- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
+-- 9,007,199,254,740,991 inclusive.
+instance TryFrom.TryFrom Int Double where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    if toInteger (maxBound :: Int) <= maxDouble
+      then Right $ fromIntegral s
+      else if s < -maxDouble
+        then Left Exception.Underflow
+        else if s > maxDouble
+          then Left Exception.Overflow
+          else Right $ fromIntegral s
+
+-- Integer
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Integer Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromInteger' when the input is not negative.
+instance TryFrom.TryFrom Integer Natural.Natural where
+  -- This should use @eitherTryFrom fromNonNegativeIntegral@, but that causes
+  -- a bug in GHC 9.0.1. By inlining @fromNonNegativeIntegral@ and replacing
+  -- @fromIntegral@ with @fromInteger@, we can work around the bug.
+  -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html
+  tryFrom = Utility.eitherTryFrom
+    $ \s -> if s < 0 then Left Exception.Underflow else Right $ fromInteger s
+
+-- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
+-- inclusive.
+instance TryFrom.TryFrom Integer Float where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
+    then Left Exception.Underflow
+    else if s > maxFloat
+      then Left Exception.Overflow
+      else Right $ fromIntegral s
+
+-- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
+-- 9,007,199,254,740,991 inclusive.
+instance TryFrom.TryFrom Integer Double where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxDouble
+    then Left Exception.Underflow
+    else if s > maxDouble
+      then Left Exception.Overflow
+      else Right $ fromIntegral s
+
+-- Word8
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Word.Word16 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Word.Word32 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Word.Word64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Word where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Natural.Natural where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word8 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Int.Int16 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Int.Int32 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Int where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Integer where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Float where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word8 Double where
+  from = fromIntegral
+
+-- Word16
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word16 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Word.Word32 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Word.Word64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Word where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Natural.Natural where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word16 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word16 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Int.Int32 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Int where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Integer where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Float where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word16 Double where
+  from = fromIntegral
+
+-- Word32
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word32 Word.Word64 where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word32 Natural.Natural where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word32 Int.Int64 where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word32 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word32 Integer where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
+instance TryFrom.TryFrom Word.Word32 Float where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word32 Double where
+  from = fromIntegral
+
+-- Word64
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word64 Natural.Natural where
+  -- This should use @fromIntegral@, but that causes a bug in GHC 9.0.1.
+  -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html
+  from s = Utility.unsafeFrom (From.from s :: Integer)
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word.Word64 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word.Word64 Integer where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
+instance TryFrom.TryFrom Word.Word64 Float where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
+
+-- | Uses 'fromIntegral' when the input is less than or equal to
+-- 9,007,199,254,740,991.
+instance TryFrom.TryFrom Word.Word64 Double where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxDouble
+    then Right $ fromIntegral s
+    else Left Exception.Overflow
+
+-- Word
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word Word.Word64 where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral'.
+instance From.From Word Natural.Natural where
+  from = fromIntegral
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Word Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Word Integer where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
+instance TryFrom.TryFrom Word Float where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
+
+-- | Uses 'fromIntegral' when the input is less than or equal to
+-- 9,007,199,254,740,991.
+instance TryFrom.TryFrom Word Double where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    if (toInteger (maxBound :: Word) <= maxDouble) || (s <= maxDouble)
+      then Right $ fromIntegral s
+      else Left Exception.Overflow
+
+-- Natural
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'Bits.toIntegralSized'.
+instance TryFrom.TryFrom Natural.Natural Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
+
+-- | Uses 'fromIntegral'.
+instance From.From Natural.Natural Integer where
+  from = fromIntegral
+
+-- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
+instance TryFrom.TryFrom Natural.Natural Float where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
+
+-- | Uses 'fromIntegral' when the input is less than or equal to
+-- 9,007,199,254,740,991.
+instance TryFrom.TryFrom Natural.Natural Double where
+  tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxDouble
+    then Right $ fromIntegral s
+    else Left Exception.Overflow
+
+-- Float
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Int.Int8 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Int.Int16 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Int.Int32 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Int.Int64 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Int where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Rational' when the input is between -16,777,215 and
+-- 16,777,215 inclusive.
+instance TryFrom.TryFrom Float Integer where
+  tryFrom = Utility.eitherTryFrom $ \s -> case Utility.tryVia @Rational s of
+    Left e -> Left $ Exception.toException e
+    Right t
+      | t < -maxFloat -> Left $ Exception.toException Exception.Underflow
+      | t > maxFloat -> Left $ Exception.toException Exception.Overflow
+      | otherwise -> Right t
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Word.Word8 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Word.Word16 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Word.Word32 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Word.Word64 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Word where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Float Natural.Natural where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Uses 'Numeric.floatToDigits' when the input is not NaN or infinity.
+instance TryFrom.TryFrom Float Rational where
+  tryFrom = Utility.eitherTryFrom realFloatToRational
+
+-- | Uses 'Float.float2Double'.
+instance From.From Float Double where
+  from = Float.float2Double
+
+-- Double
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Int.Int8 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Int.Int16 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Int.Int32 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Int.Int64 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Int where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Rational' when the input is between -9,007,199,254,740,991
+-- and 9,007,199,254,740,991 inclusive.
+instance TryFrom.TryFrom Double Integer where
+  tryFrom = Utility.eitherTryFrom $ \s -> case Utility.tryVia @Rational s of
+    Left e -> Left $ Exception.toException e
+    Right t
+      | t < -maxDouble -> Left $ Exception.toException Exception.Underflow
+      | t > maxDouble -> Left $ Exception.toException Exception.Overflow
+      | otherwise -> Right t
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Word.Word8 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Word.Word16 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Word.Word32 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Word.Word64 where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Word where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Converts via 'Integer'.
+instance TryFrom.TryFrom Double Natural.Natural where
+  tryFrom = Utility.tryVia @Integer
+
+-- | Uses 'Numeric.floatToDigits' when the input is not NaN or infinity.
+instance TryFrom.TryFrom Double Rational where
+  tryFrom = Utility.eitherTryFrom realFloatToRational
+
+-- | Uses 'Float.double2Float'. This necessarily loses some precision.
+instance From.From Double Float where
+  from = Float.double2Float
+
+-- Ratio
+
+-- | Uses '(Ratio.%)' with a denominator of 1.
+instance Integral a => From.From a (Ratio.Ratio a) where
+  from = (Ratio.% 1)
+
+-- | Uses 'Ratio.numerator' when the denominator is 1.
+instance (Eq a, Num a) => TryFrom.TryFrom (Ratio.Ratio a) a where
+  tryFrom = Utility.eitherTryFrom $ \s -> if Ratio.denominator s == 1
+    then Right $ Ratio.numerator s
+    else Left Exception.LossOfPrecision
+
+-- | Uses 'fromRational'. This necessarily loses some precision.
+instance From.From Rational Float where
+  from = fromRational
+
+-- | Uses 'fromRational'. This necessarily loses some precision.
+instance From.From Rational Double where
+  from = fromRational
+
+-- | Uses `fromRational` as long as there isn't a loss of precision.
+instance Fixed.HasResolution a => TryFrom.TryFrom Rational (Fixed.Fixed a) where
+  tryFrom = Utility.eitherTryFrom $ \s ->
+    let
+      t :: Fixed.Fixed a
+      t = fromRational s
+    in if toRational t == s then Right t else Left Exception.LossOfPrecision
+
+-- Fixed
+
+-- | Uses 'Fixed.MkFixed'. This means @from \@Integer \@Centi 2@ is @0.02@
+-- rather than @2.00@.
+instance From.From Integer (Fixed.Fixed a) where
+  from = Fixed.MkFixed
+
+-- | Uses 'Fixed.MkFixed'. This means @from \@Centi \@Integer 3.00@ is @300@
+-- rather than @3@.
+instance From.From (Fixed.Fixed a) Integer where
+  from (Fixed.MkFixed t) = t
+
+-- | Uses 'toRational'.
+instance Fixed.HasResolution a => From.From (Fixed.Fixed a) Rational where
+  from = toRational
+
+-- Complex
+
+-- | Uses '(Complex.:+)' with an imaginary part of 0.
+instance Num a => From.From a (Complex.Complex a) where
+  from = (Complex.:+ 0)
+
+-- | Uses 'Complex.realPart' when the imaginary part is 0.
+instance (Eq a, Num a) => TryFrom.TryFrom (Complex.Complex a) a where
+  tryFrom = Utility.eitherTryFrom $ \s -> if Complex.imagPart s == 0
+    then Right $ Complex.realPart s
+    else Left Exception.LossOfPrecision
+
+-- NonEmpty
+
+-- | Uses 'NonEmpty.nonEmpty'.
+instance TryFrom.TryFrom [a] (NonEmpty.NonEmpty a) where
+  tryFrom = Utility.maybeTryFrom NonEmpty.nonEmpty
+
+-- | Uses 'NonEmpty.toList'.
+instance From.From (NonEmpty.NonEmpty a) [a] where
+  from = NonEmpty.toList
+
+-- Set
+
+-- | Uses 'Set.fromList'.
+instance Ord a => From.From [a] (Set.Set a) where
+  from = Set.fromList
+
+-- | Uses 'Set.toAscList'.
+instance From.From (Set.Set a) [a] where
+  from = Set.toAscList
+
+-- IntSet
+
+-- | Uses 'IntSet.fromList'.
+instance From.From [Int] IntSet.IntSet where
+  from = IntSet.fromList
+
+-- | Uses 'IntSet.toAscList'.
+instance From.From IntSet.IntSet [Int] where
+  from = IntSet.toAscList
+
+-- Map
+
+-- | Uses 'Map.fromList'. If there are duplicate keys, later values will
+-- overwrite earlier ones.
+instance Ord k => From.From [(k, v)] (Map.Map k v) where
+  from = Map.fromList
+
+-- | Uses 'Map.toAscList'.
+instance From.From (Map.Map k v) [(k, v)] where
+  from = Map.toAscList
+
+-- IntMap
+
+-- | Uses 'IntMap.fromList'. If there are duplicate keys, later values will
+-- overwrite earlier ones.
+instance From.From [(Int, v)] (IntMap.IntMap v) where
+  from = IntMap.fromList
+
+-- | Uses 'IntMap.toAscList'.
+instance From.From (IntMap.IntMap v) [(Int, v)] where
+  from = IntMap.toAscList
+
+-- Seq
+
+-- | Uses 'Seq.fromList'.
+instance From.From [a] (Seq.Seq a) where
+  from = Seq.fromList
+
+-- | Uses 'Foldable.toList'.
+instance From.From (Seq.Seq a) [a] where
+  from = Foldable.toList
+
+-- ByteString
+
+-- | Uses 'ByteString.pack'.
+instance From.From [Word.Word8] ByteString.ByteString where
+  from = ByteString.pack
+
+-- | Uses 'ByteString.unpack'.
+instance From.From ByteString.ByteString [Word.Word8] where
+  from = ByteString.unpack
+
+-- | Uses 'LazyByteString.fromStrict'.
+instance From.From ByteString.ByteString LazyByteString.ByteString where
+  from = LazyByteString.fromStrict
+
+-- | Uses 'ShortByteString.toShort'.
+instance From.From ByteString.ByteString ShortByteString.ShortByteString where
+  from = ShortByteString.toShort
+
+-- | Uses 'Text.decodeUtf8''.
+instance TryFrom.TryFrom ByteString.ByteString Text.Text where
+  tryFrom = Utility.eitherTryFrom Text.decodeUtf8'
+
+-- | Converts via 'Text.Text'.
+instance TryFrom.TryFrom ByteString.ByteString LazyText.Text where
+  tryFrom =
+    Utility.eitherTryFrom
+      $ fmap (Utility.into @LazyText.Text)
+      . Utility.tryInto @Text.Text
+
+-- | Converts via 'Text.Text'.
+instance TryFrom.TryFrom ByteString.ByteString String where
+  tryFrom =
+    Utility.eitherTryFrom
+      $ fmap (Utility.into @String)
+      . Utility.tryInto @Text.Text
+
+-- LazyByteString
+
+-- | Uses 'LazyByteString.pack'.
+instance From.From [Word.Word8] LazyByteString.ByteString where
+  from = LazyByteString.pack
+
+-- | Uses 'LazyByteString.unpack'.
+instance From.From LazyByteString.ByteString [Word.Word8] where
+  from = LazyByteString.unpack
+
+-- | Uses 'LazyByteString.toStrict'.
+instance From.From LazyByteString.ByteString ByteString.ByteString where
+  from = LazyByteString.toStrict
+
+-- | Uses 'LazyText.decodeUtf8''.
+instance TryFrom.TryFrom LazyByteString.ByteString LazyText.Text where
+  tryFrom = Utility.eitherTryFrom LazyText.decodeUtf8'
+
+-- | Converts via 'LazyText.Text'.
+instance TryFrom.TryFrom LazyByteString.ByteString Text.Text where
+  tryFrom =
+    Utility.eitherTryFrom
+      $ fmap (Utility.into @Text.Text)
+      . Utility.tryInto @LazyText.Text
+
+-- | Converts via 'LazyText.Text'.
+instance TryFrom.TryFrom LazyByteString.ByteString String where
+  tryFrom =
+    Utility.eitherTryFrom
+      $ fmap (Utility.into @String)
+      . Utility.tryInto @LazyText.Text
+
+-- ShortByteString
+
+-- | Uses 'ShortByteString.pack'.
+instance From.From [Word.Word8] ShortByteString.ShortByteString where
+  from = ShortByteString.pack
+
+-- | Uses 'ShortByteString.unpack'.
+instance From.From ShortByteString.ShortByteString [Word.Word8] where
+  from = ShortByteString.unpack
+
+-- | Uses 'ShortByteString.fromShort'.
+instance From.From ShortByteString.ShortByteString ByteString.ByteString where
+  from = ShortByteString.fromShort
+
+-- Text
+
+-- | Uses 'LazyText.fromStrict'.
+instance From.From Text.Text LazyText.Text where
+  from = LazyText.fromStrict
+
+-- | Uses 'Text.encodeUtf8'.
+instance From.From Text.Text ByteString.ByteString where
+  from = Text.encodeUtf8
+
+-- | Converts via 'ByteString.ByteString'.
+instance From.From Text.Text LazyByteString.ByteString where
+  from = Utility.via @ByteString.ByteString
+
+-- LazyText
+
+-- | Uses 'LazyText.toStrict'.
+instance From.From LazyText.Text Text.Text where
+  from = LazyText.toStrict
+
+-- | Uses 'LazyText.encodeUtf8'.
+instance From.From LazyText.Text LazyByteString.ByteString where
+  from = LazyText.encodeUtf8
+
+-- | Converts via 'LazyByteString.ByteString'.
+instance From.From LazyText.Text ByteString.ByteString where
+  from = Utility.via @LazyByteString.ByteString
+
+-- String
+
+-- | Uses 'Text.pack'. Some 'Char' values cannot be represented in 'Text.Text'
+-- and will be replaced with @'\\xFFFD'@.
+instance From.From String Text.Text where
+  from = Text.pack
+
+-- | Uses 'Text.unpack'.
+instance From.From Text.Text String where
+  from = Text.unpack
+
+-- | Uses 'LazyText.pack'. Some 'Char' values cannot be represented in
+-- 'LazyText.Text' and will be replaced with @'\\xFFFD'@.
+instance From.From String LazyText.Text where
+  from = LazyText.pack
+
+-- | Uses 'LazyText.unpack'.
+instance From.From LazyText.Text String where
+  from = LazyText.unpack
+
+-- | Converts via 'Text.Text'.
+instance From.From String ByteString.ByteString where
+  from = Utility.via @Text.Text
+
+-- | Converts via 'LazyText.Text'.
+instance From.From String LazyByteString.ByteString where
+  from = Utility.via @LazyText.Text
+
+-- TryFromException
+
+-- | Uses @coerce@.
+instance From.From
+  (TryFromException.TryFromException source oldTarget)
+  (TryFromException.TryFromException source newTarget)
+
+-- Day
+
+-- | Uses 'Time.ModifiedJulianDay'.
+instance From.From Integer Time.Day where
+  from = Time.ModifiedJulianDay
+
+-- | Uses 'Time.toModifiedJulianDay'.
+instance From.From Time.Day Integer where
+  from = Time.toModifiedJulianDay
+
+-- DayOfWeek
+
+-- | Uses 'Time.dayOfWeek'.
+instance From.From Time.Day Time.DayOfWeek where
+  from = Time.dayOfWeek
+
+-- UniversalTime
+
+-- | Uses 'Time.ModJulianDate'.
+instance From.From Rational Time.UniversalTime where
+  from = Time.ModJulianDate
+
+-- | Uses 'Time.getModJulianDate'.
+instance From.From Time.UniversalTime Rational where
+  from = Time.getModJulianDate
+
+-- DiffTime
+
+-- | Uses 'realToFrac'.
+instance From.From Fixed.Pico Time.DiffTime where
+  from = realToFrac
+
+-- | Uses 'realToFrac'.
+instance From.From Time.DiffTime Fixed.Pico where
+  from = realToFrac
+
+-- NominalDiffTime
+
+-- | Uses 'Time.secondsToNominalDiffTime'.
+instance From.From Fixed.Pico Time.NominalDiffTime where
+  from = Time.secondsToNominalDiffTime
+
+-- | Uses 'Time.nominalDiffTimeToSeconds'.
+instance From.From Time.NominalDiffTime Fixed.Pico where
+  from = Time.nominalDiffTimeToSeconds
+
+-- POSIXTime
+
+-- | Uses 'Time.systemToPOSIXTime'.
+instance From.From Time.SystemTime Time.POSIXTime where
+  from = Time.systemToPOSIXTime
+
+-- | Uses 'Time.utcTimeToPOSIXSeconds'.
+instance From.From Time.UTCTime Time.POSIXTime where
+  from = Time.utcTimeToPOSIXSeconds
+
+-- | Uses 'Time.posixSecondsToUTCTime'.
+instance From.From Time.POSIXTime Time.UTCTime where
+  from = Time.posixSecondsToUTCTime
+
+-- SystemTime
+
+-- | Uses 'Time.utcToSystemTime'.
+instance From.From Time.UTCTime Time.SystemTime where
+  from = Time.utcToSystemTime
+
+-- | Uses 'Time.systemToTAITime'.
+instance From.From Time.SystemTime Time.AbsoluteTime where
+  from = Time.systemToTAITime
+
+-- | Uses 'Time.systemToUTCTime'.
+instance From.From Time.SystemTime Time.UTCTime where
+  from = Time.systemToUTCTime
+
+-- TimeOfDay
+
+-- | Uses 'Time.timeToTimeOfDay'.
+instance From.From Time.DiffTime Time.TimeOfDay where
+  from = Time.timeToTimeOfDay
+
+-- | Uses 'Time.dayFractionToTimeOfDay'.
+instance From.From Rational Time.TimeOfDay where
+  from = Time.dayFractionToTimeOfDay
+
+-- | Uses 'Time.timeOfDayToTime'.
+instance From.From Time.TimeOfDay Time.DiffTime where
+  from = Time.timeOfDayToTime
+
+-- | Uses 'Time.timeOfDayToDayFraction'.
+instance From.From Time.TimeOfDay Rational where
+  from = Time.timeOfDayToDayFraction
+
+-- CalendarDiffTime
+
+-- | Uses 'Time.calendarTimeDays'.
+instance From.From Time.CalendarDiffDays Time.CalendarDiffTime where
+  from = Time.calendarTimeDays
+
+-- | Uses 'Time.calendarTimeTime'.
+instance From.From Time.NominalDiffTime Time.CalendarDiffTime where
+  from = Time.calendarTimeTime
+
+-- ZonedTime
+
+-- | Uses 'Time.zonedTimeToUTC'.
+instance From.From Time.ZonedTime Time.UTCTime where
+  from = Time.zonedTimeToUTC
+
+--
+
+realFloatToRational
+  :: RealFloat s => s -> Either Exception.ArithException Rational
+realFloatToRational s
+  | isNaN s = Left Exception.LossOfPrecision
+  | isInfinite s = if s > 0
+    then Left Exception.Overflow
+    else Left Exception.Underflow
+  | otherwise = Right $ overPositive
+    (uncurry makeRational . uncurry fromDigits . Numeric.floatToDigits 10)
+    s
+
+overPositive :: (Eq a, Num a, Num b) => (a -> b) -> a -> b
+overPositive f x = if signum x == -1 then -(f (-x)) else f x
+
+fromDigits :: [Int] -> Int -> (Integer, Integer)
+fromDigits ds e =
+  List.foldl' (\(a, n) d -> (a * 10 + toInteger d, n - 1)) (0, toInteger e) ds
+
+makeRational :: Integer -> Integer -> Rational
+makeRational d e = toRational d * 10 ^^ e
+
+fromNonNegativeIntegral
+  :: (Integral s, Num t) => s -> Either Exception.ArithException t
+fromNonNegativeIntegral x =
+  if x < 0 then Left Exception.Underflow else Right $ fromIntegral x
+
+-- | The maximum integral value that can be unambiguously represented as a
+-- 'Float'. Equal to 16,777,215.
+maxFloat :: Num a => a
+maxFloat = 16777215
+
+-- | The maximum integral value that can be unambiguously represented as a
+-- 'Double'. Equal to 9,007,199,254,740,991.
+maxDouble :: Num a => a
+maxDouble = 9007199254740991
diff --git a/source/library/Witch/TryFrom.hs b/source/library/Witch/TryFrom.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch/TryFrom.hs
@@ -0,0 +1,26 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module Witch.TryFrom where
+
+import qualified Witch.TryFromException as TryFromException
+
+-- | This type class is for converting values from some @source@ type into
+-- some other @target@ type. The constraint @'TryFrom' source target@ means
+-- that you may be able to convert from a value of type @source@ into a value
+-- of type @target@, but that conversion may fail at runtime.
+--
+-- This type class is for conversions that can sometimes fail. If your
+-- conversion always succeeds, consider implementing @From@ instead.
+class TryFrom source target where
+  -- | This method implements the conversion of a value between types. At call
+  -- sites you may want to use @tryInto@ instead.
+  --
+  -- > -- Avoid this:
+  -- > tryFrom (x :: s)
+  -- >
+  -- > -- Prefer this:
+  -- > tryFrom @s
+  --
+  -- Consider using @maybeTryFrom@ or @eitherTryFrom@ to implement this
+  -- method.
+  tryFrom :: source -> Either (TryFromException.TryFromException source target) target
diff --git a/source/library/Witch/TryFromException.hs b/source/library/Witch/TryFromException.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch/TryFromException.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Witch.TryFromException where
+
+import qualified Control.Exception as Exception
+import qualified Data.Proxy as Proxy
+import qualified Data.Typeable as Typeable
+
+-- | This exception is thrown when a @TryFrom@ conversion fails. It has the
+-- original @source@ value that caused the failure and it knows the @target@
+-- type it was trying to convert into. It also has an optional
+-- 'Exception.SomeException' for communicating what went wrong while
+-- converting.
+data TryFromException source target = TryFromException
+  source
+  (Maybe Exception.SomeException)
+
+instance
+  ( Show source
+  , Typeable.Typeable source
+  , Typeable.Typeable target
+  ) => Show (TryFromException source target) where
+  showsPrec d (TryFromException x e) =
+    showParen (d > 10)
+      $ showString "TryFromException @"
+      . showsPrec 11 (Typeable.typeRep (Proxy.Proxy :: Proxy.Proxy source))
+      . showString " @"
+      . showsPrec 11 (Typeable.typeRep (Proxy.Proxy :: Proxy.Proxy target))
+      . showChar ' '
+      . showsPrec 11 x
+      . showChar ' '
+      . showsPrec 11 e
+
+instance
+  ( Show source
+  , Typeable.Typeable source
+  , Typeable.Typeable target
+  ) => Exception.Exception (TryFromException source target)
diff --git a/source/library/Witch/Utility.hs b/source/library/Witch/Utility.hs
new file mode 100644
--- /dev/null
+++ b/source/library/Witch/Utility.hs
@@ -0,0 +1,199 @@
+{-# LANGUAGE AllowAmbiguousTypes #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Witch.Utility where
+
+import qualified Control.Exception as Exception
+import qualified Data.Coerce as Coerce
+import qualified Data.Typeable as Typeable
+import qualified GHC.Stack as Stack
+import qualified Witch.From as From
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.TryFromException as TryFromException
+
+-- | This is the same as 'id'. This can be an ergonomic way to pin down a
+-- polymorphic type in a function pipeline. For example:
+--
+-- > -- Avoid this:
+-- > f . (\ x -> x :: Int) . g
+-- >
+-- > -- Prefer this:
+-- > f . as @Int . g
+as :: forall source . source -> source
+as = id
+
+-- | This is the same as 'From.from' except that the type variables are in the
+-- opposite order.
+--
+-- > -- Avoid this:
+-- > from x :: t
+-- >
+-- > -- Prefer this:
+-- > into @t x
+into :: forall target source . From.From source target => source -> target
+into = From.from
+
+-- | This function converts from some @source@ type into some @target@ type,
+-- applies the given function, then converts back into the @source@ type. This
+-- is useful when you have two types that are isomorphic but some function
+-- that only works with one of them.
+--
+-- > -- Avoid this:
+-- > from @t . f . into @t
+-- >
+-- > -- Prefer this:
+-- > over @t f
+over
+  :: forall target source
+   . (From.From source target, From.From target source)
+  => (target -> target)
+  -> source
+  -> source
+over f = From.from . f . From.from
+
+-- | This function first converts from some @source@ type into some @through@
+-- type, and then converts that into some @target@ type. Usually this is used
+-- when writing 'From.From' instances. Sometimes this can be used to work
+-- around the lack of an instance that should probably exist.
+--
+-- > -- Avoid this:
+-- > from @u . into @u
+-- >
+-- > -- Prefer this:
+-- > via @u
+via
+  :: forall through source target
+   . (From.From source through, From.From through target)
+  => source
+  -> target
+via = From.from . (\x -> x :: through) . From.from
+
+-- | This is the same as 'TryFrom.tryFrom' except that the type variables are
+-- in the opposite order.
+--
+-- > -- Avoid this:
+-- > tryFrom x :: Either (TryFromException s t) t
+-- >
+-- > -- Prefer this:
+-- > tryInto @t x
+tryInto
+  :: forall target source
+   . TryFrom.TryFrom source target
+  => source
+  -> Either (TryFromException.TryFromException source target) target
+tryInto = TryFrom.tryFrom
+
+-- | This is similar to 'via' except that it works with 'TryFrom.TryFrom'
+-- instances instead. This function is especially convenient because juggling
+-- the types in the 'TryFromException.TryFromException' can be tedious.
+--
+-- > -- Avoid this:
+-- > case tryInto @u x of
+-- >   Left (TryFromException _ e) -> Left $ TryFromException x e
+-- >   Right y -> case tryFrom @u y of
+-- >     Left (TryFromException _ e) -> Left $ TryFromException x e
+-- >     Right z -> Right z
+-- >
+-- > -- Prefer this:
+-- > tryVia @u
+tryVia
+  :: forall through source target
+   . (TryFrom.TryFrom source through, TryFrom.TryFrom through target)
+  => source
+  -> Either (TryFromException.TryFromException source target) target
+tryVia s = case TryFrom.tryFrom s of
+  Left e -> Left $ withTarget e
+  Right u -> case TryFrom.tryFrom (u :: through) of
+    Left e -> Left $ withSource s e
+    Right t -> Right t
+
+-- | This function can be used to implement 'TryFrom.tryFrom' with a function
+-- that returns 'Maybe'. For example:
+--
+-- > -- Avoid this:
+-- > tryFrom s = case f s of
+-- >   Nothing -> Left $ TryFromException s Nothing
+-- >   Just t -> Right t
+-- >
+-- > -- Prefer this:
+-- > tryFrom = maybeTryFrom f
+maybeTryFrom
+  :: (source -> Maybe target)
+  -> source
+  -> Either (TryFromException.TryFromException source target) target
+maybeTryFrom f s = case f s of
+  Nothing -> Left $ TryFromException.TryFromException s Nothing
+  Just t -> Right t
+
+-- | This function can be used to implement 'TryFrom.tryFrom' with a function
+-- that returns 'Either'. For example:
+--
+-- > -- Avoid this:
+-- > tryFrom s = case f s of
+-- >   Left e -> Left . TryFromException s . Just $ toException e
+-- >   Right t -> Right t
+-- >
+-- > -- Prefer this:
+-- > tryFrom = eitherTryFrom f
+eitherTryFrom
+  :: Exception.Exception exception
+  => (source -> Either exception target)
+  -> source
+  -> Either (TryFromException.TryFromException source target) target
+eitherTryFrom f s = case f s of
+  Left e ->
+    Left . TryFromException.TryFromException s . Just $ Exception.toException e
+  Right t -> Right t
+
+-- | This function is like 'TryFrom.tryFrom' except that it will throw an
+-- impure exception if the conversion fails.
+--
+-- > -- Avoid this:
+-- > either throw id . tryFrom @s
+-- >
+-- > -- Prefer this:
+-- > unsafeFrom @s
+unsafeFrom
+  :: forall source target
+   . ( Stack.HasCallStack
+     , TryFrom.TryFrom source target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     )
+  => source
+  -> target
+unsafeFrom = either Exception.throw id . TryFrom.tryFrom
+
+-- | This function is like 'tryInto' except that it will throw an impure
+-- exception if the conversion fails.
+--
+-- > -- Avoid this:
+-- > either throw id . tryInto @t
+-- >
+-- > -- Prefer this:
+-- > unsafeInto @t
+unsafeInto
+  :: forall target source
+   . ( Stack.HasCallStack
+     , TryFrom.TryFrom source target
+     , Show source
+     , Typeable.Typeable source
+     , Typeable.Typeable target
+     )
+  => source
+  -> target
+unsafeInto = unsafeFrom
+
+withSource
+  :: newSource
+  -> TryFromException.TryFromException oldSource target
+  -> TryFromException.TryFromException newSource target
+withSource x (TryFromException.TryFromException _ e) =
+  TryFromException.TryFromException x e
+
+withTarget
+  :: forall newTarget source oldTarget
+   . TryFromException.TryFromException source oldTarget
+  -> TryFromException.TryFromException source newTarget
+withTarget = Coerce.coerce
diff --git a/source/test-suite/Main.hs b/source/test-suite/Main.hs
new file mode 100644
--- /dev/null
+++ b/source/test-suite/Main.hs
@@ -0,0 +1,1981 @@
+{-# OPTIONS_GHC -Wno-error=overflowed-literals #-}
+
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE NegativeLiterals #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeApplications #-}
+
+import qualified Control.Exception as Exception
+import qualified Data.ByteString as ByteString
+import qualified Data.ByteString.Lazy as LazyByteString
+import qualified Data.ByteString.Short as ShortByteString
+import qualified Data.Complex as Complex
+import qualified Data.Either as Either
+import qualified Data.Fixed as Fixed
+import qualified Data.Int as Int
+import qualified Data.IntMap as IntMap
+import qualified Data.IntSet as IntSet
+import qualified Data.List.NonEmpty as NonEmpty
+import qualified Data.Map as Map
+import qualified Data.Ratio as Ratio
+import qualified Data.Sequence as Seq
+import qualified Data.Set as Set
+import qualified Data.Text as Text
+import qualified Data.Text.Lazy as LazyText
+import qualified Data.Time as Time
+import qualified Data.Time.Clock.POSIX as Time
+import qualified Data.Time.Clock.System as Time
+import qualified Data.Time.Clock.TAI as Time
+import qualified Data.Word as Word
+import qualified Numeric.Natural as Natural
+import Test.HUnit (Test(TestCase), assertBool, runTestTTAndExit, (~:), (~?=))
+import qualified Witch
+
+main :: IO ()
+main =
+  runTestTTAndExit
+    $ "Witch"
+    ~: [ "From"
+         ~: ["from" ~: [Witch.from (1 :: Int.Int8) ~?= (1 :: Int.Int16)]]
+       , "TryFrom"
+         ~: [ "tryFrom"
+                ~: let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8
+                   in [f 1 ~?= Just 1, f 128 ~?= Nothing]
+            ]
+       , "Utility"
+         ~: [ "as" ~: [Witch.as @Int.Int8 1 ~?= 1]
+            , "from" ~: [Witch.from @Int.Int8 1 ~?= (1 :: Int.Int16)]
+            , "into" ~: [Witch.into @Int.Int16 (1 :: Int.Int8) ~?= 1]
+            , "over" ~: [Witch.over @Int.Int8 (+ 1) (Age 1) ~?= Age 2]
+            , "via"
+              ~: [Witch.via @Int.Int16 (1 :: Int.Int8) ~?= (1 :: Int.Int32)]
+            , "tryFrom"
+              ~: [hush (Witch.tryFrom @Int.Int16 1) ~?= Just (1 :: Int.Int8)]
+            , "tryInto"
+              ~: [hush (Witch.tryInto @Int.Int8 (1 :: Int.Int16)) ~?= Just 1]
+            , "tryVia"
+              ~: let f = Witch.tryVia @Int.Int16 @Int.Int32 @Int.Int8
+                 in
+                   [ hush (f 1) ~?= Just 1
+                   , hush (f 128) ~?= Nothing
+                   , hush (f 32768) ~?= Nothing
+                   ]
+            , "unsafeFrom"
+              ~: let f = Witch.unsafeFrom @Int.Int16 @Int.Int8
+                 in
+                   [ f 1 ~?= 1
+                   , TestCase $ do
+                     result <-
+                       Exception.try @Exception.SomeException
+                       . Exception.evaluate
+                       $ f 128
+                     assertBool (show result) $ Either.isLeft result
+                   ]
+            , "unsafeInto"
+              ~: [Witch.unsafeInto @Int.Int8 (1 :: Int.Int16) ~?= 1]
+            ]
+       , "Lift"
+         ~: [ "liftedFrom"
+              ~: [($$(Witch.liftedFrom (1 :: Int.Int16)) :: Int.Int8) ~?= 1]
+            , "liftedInto"
+              ~: [$$(Witch.liftedInto @Int.Int8 (1 :: Int.Int16)) ~?= 1]
+            ]
+       , "TryFromException"
+         ~: [ "show"
+                ~: [ show (Witch.TryFromException @Int @Int 0 Nothing)
+                     ~?= "TryFromException @Int @Int 0 Nothing"
+                   , show
+                       (Witch.TryFromException @(Seq.Seq Int) @(Seq.Seq Int)
+                         (Seq.fromList [])
+                         (Just (Exception.toException Exception.Overflow))
+                       )
+                     ~?= "TryFromException @(Seq Int) @(Seq Int) (fromList []) (Just arithmetic overflow)"
+                   ]
+            ]
+       , "Instances"
+         ~: [ "From a a" ~: let f = Witch.from @Int @Int in [f 0 ~?= 0]
+
+    -- Int8
+            , "From Int8 Int16"
+              ~: let f = Witch.from @Int.Int8 @Int.Int16
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+            , "From Int8 Int32"
+              ~: let f = Witch.from @Int.Int8 @Int.Int32
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+            , "From Int8 Int64"
+              ~: let f = Witch.from @Int.Int8 @Int.Int64
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+            , "From Int8 Int"
+              ~: let f = Witch.from @Int.Int8 @Int
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+            , "From Int8 Integer"
+              ~: let f = Witch.from @Int.Int8 @Integer
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+            , "TryFrom Int8 Word8"
+              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "TryFrom Int8 Word16"
+              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word16
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "TryFrom Int8 Word32"
+              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word32
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "TryFrom Int8 Word64"
+              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word64
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "TryFrom Int8 Word"
+              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "TryFrom Int8 Natural"
+              ~: let f = hush . Witch.tryFrom @Int.Int8 @Natural.Natural
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "From Int8 Float"
+              ~: let f = Witch.from @Int.Int8 @Float
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+            , "From Int8 Double"
+              ~: let f = Witch.from @Int.Int8 @Double
+                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
+
+    -- Int16
+            , "TryFrom Int16 Int8"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   ]
+            , "From Int16 Int32"
+              ~: let f = Witch.from @Int.Int16 @Int.Int32
+                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
+            , "From Int16 Int64"
+              ~: let f = Witch.from @Int.Int16 @Int.Int64
+                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
+            , "From Int16 Int"
+              ~: let f = Witch.from @Int.Int16 @Int
+                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
+            , "From Int16 Integer"
+              ~: let f = Witch.from @Int.Int16 @Integer
+                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
+            , "TryFrom Int16 Word8"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int16 Word16"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word16
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
+            , "TryFrom Int16 Word32"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word32
+                 in
+                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
+            , "TryFrom Int16 Word64"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word64
+                 in
+                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
+            , "TryFrom Int16 Word"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word
+                 in
+                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
+            , "TryFrom Int16 Natural"
+              ~: let f = hush . Witch.tryFrom @Int.Int16 @Natural.Natural
+                 in
+                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
+            , "From Int16 Float"
+              ~: let f = Witch.from @Int.Int16 @Float
+                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
+            , "From Int16 Double"
+              ~: let f = Witch.from @Int.Int16 @Double
+                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
+
+    -- Int32
+            , "TryFrom Int32 Int8"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Int16"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   , f (-32768) ~?= Just (-32768)
+                   , f (-32769) ~?= Nothing
+                   ]
+            , "From Int32 Int64"
+              ~: let f = Witch.from @Int.Int32 @Int.Int64
+                 in
+                   [ f 0 ~?= 0
+                   , f 2147483647 ~?= 2147483647
+                   , f (-2147483648) ~?= (-2147483648)
+                   ]
+            , "TryFrom Int32 Int"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f (-2147483648) ~?= Just (-2147483648)
+                   ]
+            , "From Int32 Integer"
+              ~: let f = Witch.from @Int.Int32 @Integer
+                 in
+                   [ f 0 ~?= 0
+                   , f 2147483647 ~?= 2147483647
+                   , f (-2147483648) ~?= (-2147483648)
+                   ]
+            , "TryFrom Int32 Word8"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Word16"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Word32"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Word64"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Word"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Natural"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Natural.Natural
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int32 Float"
+              ~: let f = hush . Witch.tryFrom @Int.Int32 @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   ]
+            , "From Int32 Double"
+              ~: let f = Witch.from @Int.Int32 @Double
+                 in
+                   [ f 0 ~?= 0
+                   , f 2147483647 ~?= 2147483647
+                   , f (-2147483648) ~?= (-2147483648)
+                   ]
+
+    -- Int64
+            , "TryFrom Int64 Int8"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Int16"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   , f (-32768) ~?= Just (-32768)
+                   , f (-32769) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Int32"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   , f (-2147483648) ~?= Just (-2147483648)
+                   , f (-2147483649) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Int"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 9223372036854775807
+                         then f 9223372036854775807
+                           ~?= Just 9223372036854775807
+                         else f (fromIntegral x) ~?= Just x
+                   , let x = minBound :: Int
+                     in
+                       if toInteger x <= (-9223372036854775808)
+                         then f (-9223372036854775808)
+                           ~?= Just (-9223372036854775808)
+                         else f (fromIntegral x) ~?= Just x
+                   ]
+            , "From Int64 Integer"
+              ~: let f = Witch.from @Int.Int64 @Integer
+                 in
+                   [ f 0 ~?= 0
+                   , f 9223372036854775807 ~?= 9223372036854775807
+                   , f (-9223372036854775808) ~?= (-9223372036854775808)
+                   ]
+            , "TryFrom Int64 Word8"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Word16"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Word32"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Word64"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9223372036854775807 ~?= Just 9223372036854775807
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Word"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 9223372036854775807
+                         then f 9223372036854775807
+                           ~?= Just 9223372036854775807
+                         else f (fromIntegral x) ~?= Just x
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Natural"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Natural.Natural
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9223372036854775807 ~?= Just 9223372036854775807
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Float"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   ]
+            , "TryFrom Int64 Double"
+              ~: let f = hush . Witch.tryFrom @Int.Int64 @Double
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   , f (-9007199254740991) ~?= Just (-9007199254740991)
+                   , f (-9007199254740992) ~?= Nothing
+                   ]
+
+    -- Int
+            , "TryFrom Int Int8"
+              ~: let f = hush . Witch.tryFrom @Int @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   ]
+            , "TryFrom Int Int16"
+              ~: let f = hush . Witch.tryFrom @Int @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   , f (-32768) ~?= Just (-32768)
+                   , f (-32769) ~?= Nothing
+                   ]
+            , "TryFrom Int Int32"
+              ~: let f = hush . Witch.tryFrom @Int @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 2147483648
+                         then f 2147483648 ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   , f (-2147483648) ~?= Just (-2147483648)
+                   , let x = minBound :: Int
+                     in
+                       if toInteger x <= (-2147483649)
+                         then f (-2147483649) ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   ]
+            , "From Int Int64"
+              ~: let f = Witch.from @Int @Int.Int64
+                 in
+                   [ f 0 ~?= 0
+                   , f maxBound ~?= fromIntegral (maxBound :: Int)
+                   , f minBound ~?= fromIntegral (minBound :: Int)
+                   ]
+            , "From Int Integer"
+              ~: let f = Witch.from @Int @Integer
+                 in
+                   [ f 0 ~?= 0
+                   , f maxBound ~?= fromIntegral (maxBound :: Int)
+                   , f minBound ~?= fromIntegral (minBound :: Int)
+                   ]
+            , "TryFrom Int Word8"
+              ~: let f = hush . Witch.tryFrom @Int @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int Word16"
+              ~: let f = hush . Witch.tryFrom @Int @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int Word32"
+              ~: let f = hush . Witch.tryFrom @Int @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 4294967295
+                         then f 4294967295 ~?= Just 4294967295
+                         else f x ~?= Just (fromIntegral x)
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 4294967296
+                         then f 4294967296 ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int Word64"
+              ~: let f = hush . Witch.tryFrom @Int @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f maxBound ~?= Just (fromIntegral (maxBound :: Int))
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int Word"
+              ~: let f = hush . Witch.tryFrom @Int @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , f maxBound ~?= Just (fromIntegral (maxBound :: Int))
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int Natural"
+              ~: let f = hush . Witch.tryFrom @Int @Natural.Natural
+                 in
+                   [ f 0 ~?= Just 0
+                   , f maxBound ~?= Just (fromIntegral (maxBound :: Int))
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Int Float"
+              ~: let f = hush . Witch.tryFrom @Int @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   ]
+            , "TryFrom Int Double"
+              ~: let f = hush . Witch.tryFrom @Int @Double
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 9007199254740991
+                         then f 9007199254740991 ~?= Just 9007199254740991
+                         else f x ~?= Just (fromIntegral x)
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 9007199254740992
+                         then f 9007199254740992 ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   , let x = minBound :: Int
+                     in
+                       if toInteger x <= (-9007199254740991)
+                         then f (-9007199254740991)
+                           ~?= Just (-9007199254740991)
+                         else f x ~?= Just (fromIntegral x)
+                   , let x = minBound :: Int
+                     in
+                       if toInteger x <= (-9007199254740992)
+                         then f (-9007199254740992) ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   ]
+
+    -- Integer
+            , "TryFrom Integer Int8"
+              ~: let f = hush . Witch.tryFrom @Integer @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   ]
+            , "TryFrom Integer Int16"
+              ~: let f = hush . Witch.tryFrom @Integer @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   , f (-32768) ~?= Just (-32768)
+                   , f (-32769) ~?= Nothing
+                   ]
+            , "TryFrom Integer Int32"
+              ~: let f = hush . Witch.tryFrom @Integer @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   , f (-2147483648) ~?= Just (-2147483648)
+                   , f (-2147483649) ~?= Nothing
+                   ]
+            , "TryFrom Integer Int64"
+              ~: let f = hush . Witch.tryFrom @Integer @Int.Int64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9223372036854775807 ~?= Just 9223372036854775807
+                   , f 9223372036854775808 ~?= Nothing
+                   , f (-9223372036854775808) ~?= Just (-9223372036854775808)
+                   , f (-9223372036854775809) ~?= Nothing
+                   ]
+            , "TryFrom Integer Int"
+              ~: let f = hush . Witch.tryFrom @Integer @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int in f (fromIntegral x) ~?= Just x
+                   , let x = toInteger (maxBound :: Int) + 1
+                     in f x ~?= Nothing
+                   , let x = minBound :: Int in f (fromIntegral x) ~?= Just x
+                   , let x = toInteger (minBound :: Int) - 1
+                     in f x ~?= Nothing
+                   ]
+            , "TryFrom Integer Word8"
+              ~: let f = hush . Witch.tryFrom @Integer @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Integer Word16"
+              ~: let f = hush . Witch.tryFrom @Integer @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Integer Word32"
+              ~: let f = hush . Witch.tryFrom @Integer @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 4294967295 ~?= Just 4294967295
+                   , f 4294967296 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Integer Word64"
+              ~: let f = hush . Witch.tryFrom @Integer @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 18446744073709551615 ~?= Just 18446744073709551615
+                   , f 18446744073709551616 ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Integer Word"
+              ~: let f = hush . Witch.tryFrom @Integer @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word in f (fromIntegral x) ~?= Just x
+                   , let x = toInteger (maxBound :: Word) + 1
+                     in f x ~?= Nothing
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Integer Natural"
+              ~: let f = hush . Witch.tryFrom @Integer @Natural.Natural
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 18446744073709551616 ~?= Just 18446744073709551616
+                   , f (-1) ~?= Nothing
+                   ]
+            , "TryFrom Integer Float"
+              ~: let f = hush . Witch.tryFrom @Integer @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   ]
+            , "TryFrom Integer Double"
+              ~: let f = hush . Witch.tryFrom @Integer @Double
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   , f (-9007199254740991) ~?= Just (-9007199254740991)
+                   , f (-9007199254740992) ~?= Nothing
+                   ]
+
+    -- Word8
+            , "From Word8 Word16"
+              ~: let f = Witch.from @Word.Word8 @Word.Word16
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Word32"
+              ~: let f = Witch.from @Word.Word8 @Word.Word32
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Word64"
+              ~: let f = Witch.from @Word.Word8 @Word.Word64
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Word"
+              ~: let f = Witch.from @Word.Word8 @Word
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Natural"
+              ~: let f = Witch.from @Word.Word8 @Natural.Natural
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "TryFrom Word8 Int8"
+              ~: let f = hush . Witch.tryFrom @Word.Word8 @Int.Int8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
+            , "From Word8 Int16"
+              ~: let f = Witch.from @Word.Word8 @Int.Int16
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Int32"
+              ~: let f = Witch.from @Word.Word8 @Int.Int32
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Int64"
+              ~: let f = Witch.from @Word.Word8 @Int.Int64
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Int"
+              ~: let f = Witch.from @Word.Word8 @Int
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Integer"
+              ~: let f = Witch.from @Word.Word8 @Integer
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Float"
+              ~: let f = Witch.from @Word.Word8 @Float
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+            , "From Word8 Double"
+              ~: let f = Witch.from @Word.Word8 @Double
+                 in [f 0 ~?= 0, f 255 ~?= 255]
+
+    -- Word16
+            , "TryFrom Word16 Word8"
+              ~: let f = hush . Witch.tryFrom @Word.Word16 @Word.Word8
+                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
+            , "From Word16 Word32"
+              ~: let f = Witch.from @Word.Word16 @Word.Word32
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Word64"
+              ~: let f = Witch.from @Word.Word16 @Word.Word64
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Word"
+              ~: let f = Witch.from @Word.Word16 @Word
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Natural"
+              ~: let f = Witch.from @Word.Word16 @Natural.Natural
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "TryFrom Word16 Int8"
+              ~: let f = hush . Witch.tryFrom @Word.Word16 @Int.Int8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
+            , "TryFrom Word16 Int16"
+              ~: let f = hush . Witch.tryFrom @Word.Word16 @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   ]
+            , "From Word16 Int32"
+              ~: let f = Witch.from @Word.Word16 @Int.Int32
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Int64"
+              ~: let f = Witch.from @Word.Word16 @Int.Int64
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Int"
+              ~: let f = Witch.from @Word.Word16 @Int
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Integer"
+              ~: let f = Witch.from @Word.Word16 @Integer
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Float"
+              ~: let f = Witch.from @Word.Word16 @Float
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+            , "From Word16 Double"
+              ~: let f = Witch.from @Word.Word16 @Double
+                 in [f 0 ~?= 0, f 65535 ~?= 65535]
+
+    -- Word32
+            , "TryFrom Word32 Word8"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Word.Word8
+                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
+            , "TryFrom Word32 Word16"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   ]
+            , "From Word32 Word64"
+              ~: let f = Witch.from @Word.Word32 @Word.Word64
+                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
+            , "TryFrom Word32 Word"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Word
+                 in [f 0 ~?= Just 0, f 4294967295 ~?= Just 4294967295]
+            , "From Word32 Natural"
+              ~: let f = Witch.from @Word.Word32 @Natural.Natural
+                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
+            , "TryFrom Word32 Int8"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
+            , "TryFrom Word32 Int16"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   ]
+            , "TryFrom Word32 Int32"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   ]
+            , "From Word32 Int64"
+              ~: let f = Witch.from @Word.Word32 @Int.Int64
+                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
+            , "TryFrom Word32 Int"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 4294967295
+                         then f 4294967295 ~?= Just 4294967295
+                         else f (fromIntegral x) ~?= Just x
+                   ]
+            , "From Word32 Integer"
+              ~: let f = Witch.from @Word.Word32 @Integer
+                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
+            , "TryFrom Word32 Float"
+              ~: let f = hush . Witch.tryFrom @Word.Word32 @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   ]
+            , "From Word32 Double"
+              ~: let f = Witch.from @Word.Word32 @Double
+                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
+
+    -- Word64
+            , "TryFrom Word64 Word8"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word8
+                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
+            , "TryFrom Word64 Word16"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   ]
+            , "TryFrom Word64 Word32"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 4294967295 ~?= Just 4294967295
+                   , f 4294967296 ~?= Nothing
+                   ]
+            , "TryFrom Word64 Word"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 18446744073709551615
+                         then f 18446744073709551615
+                           ~?= Just 18446744073709551615
+                         else f (fromIntegral x) ~?= Just x
+                   ]
+            , "From Word64 Natural"
+              ~: let f = Witch.from @Word.Word64 @Natural.Natural
+                 in
+                   [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615]
+            , "TryFrom Word64 Int8"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
+            , "TryFrom Word64 Int16"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   ]
+            , "TryFrom Word64 Int32"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   ]
+            , "TryFrom Word64 Int64"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9223372036854775807 ~?= Just 9223372036854775807
+                   , f 9223372036854775808 ~?= Nothing
+                   ]
+            , "TryFrom Word64 Int"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       hush (Witch.tryFrom @Word.Word64 @Int (fromIntegral x))
+                         ~?= Just x
+                   , let x = fromIntegral (maxBound :: Int) + 1 :: Word.Word64
+                     in hush (Witch.tryFrom @Word.Word64 @Int x) ~?= Nothing
+                   ]
+            , "From Word64 Integer"
+              ~: let f = Witch.from @Word.Word64 @Integer
+                 in
+                   [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615]
+            , "TryFrom Word64 Float"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   ]
+            , "TryFrom Word64 Double"
+              ~: let f = hush . Witch.tryFrom @Word.Word64 @Double
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   ]
+
+    -- Word
+            , "TryFrom Word Word8"
+              ~: let f = hush . Witch.tryFrom @Word @Word.Word8
+                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
+            , "TryFrom Word Word16"
+              ~: let f = hush . Witch.tryFrom @Word @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   ]
+            , "TryFrom Word Word32"
+              ~: let f = hush . Witch.tryFrom @Word @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 4294967295 ~?= Just 4294967295
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 4294967296
+                         then f 4294967296 ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   ]
+            , "From Word Word64"
+              ~: let f = Witch.from @Word @Word.Word64
+                 in [f 0 ~?= 0, f maxBound ~?= fromIntegral (maxBound :: Word)]
+            , "From Word Natural"
+              ~: let f = Witch.from @Word @Natural.Natural
+                 in [f 0 ~?= 0, f maxBound ~?= fromIntegral (maxBound :: Word)]
+            , "TryFrom Word Int8"
+              ~: let f = hush . Witch.tryFrom @Word @Int.Int8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
+            , "TryFrom Word Int16"
+              ~: let f = hush . Witch.tryFrom @Word @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   ]
+            , "TryFrom Word Int32"
+              ~: let f = hush . Witch.tryFrom @Word @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   ]
+            , "TryFrom Word Int64"
+              ~: let f = hush . Witch.tryFrom @Word @Int.Int64
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 9223372036854775807
+                         then f 9223372036854775807
+                           ~?= Just 9223372036854775807
+                         else f x ~?= Just (fromIntegral x)
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 9223372036854775808
+                         then f 9223372036854775808 ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   ]
+            , "TryFrom Word Int"
+              ~: let f = hush . Witch.tryFrom @Word @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       hush (Witch.tryFrom @Word @Int (fromIntegral x))
+                         ~?= Just x
+                   , let x = fromIntegral (maxBound :: Int) + 1 :: Word
+                     in hush (Witch.tryFrom @Word @Int x) ~?= Nothing
+                   ]
+            , "From Word Integer"
+              ~: let f = Witch.from @Word @Integer
+                 in [f 0 ~?= 0, f maxBound ~?= fromIntegral (maxBound :: Word)]
+            , "TryFrom Word Float"
+              ~: let f = hush . Witch.tryFrom @Word @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   ]
+            , "TryFrom Word Double"
+              ~: let f = hush . Witch.tryFrom @Word @Double
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 9007199254740991
+                         then f 9007199254740991 ~?= Just 9007199254740991
+                         else f x ~?= Just (fromIntegral x)
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 9007199254740992
+                         then f 9007199254740992 ~?= Nothing
+                         else f x ~?= Just (fromIntegral x)
+                   ]
+
+    -- Natural
+            , "TryFrom Natural Word8"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word8
+                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
+            , "TryFrom Natural Word16"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   ]
+            , "TryFrom Natural Word32"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 4294967295 ~?= Just 4294967295
+                   , f 4294967296 ~?= Nothing
+                   ]
+            , "TryFrom Natural Word64"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 18446744073709551615 ~?= Just 18446744073709551615
+                   , f 18446744073709551616 ~?= Nothing
+                   ]
+            , "TryFrom Natural Word"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word
+                     in
+                       hush
+                           (Witch.tryFrom @Natural.Natural @Word
+                             (fromIntegral x)
+                           )
+                         ~?= Just x
+                   , let
+                       x =
+                         fromIntegral (maxBound :: Word) + 1 :: Natural.Natural
+                     in
+                       hush (Witch.tryFrom @Natural.Natural @Word x)
+                         ~?= Nothing
+                   ]
+            , "TryFrom Natural Int8"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int8
+                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
+            , "TryFrom Natural Int16"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   ]
+            , "TryFrom Natural Int32"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   ]
+            , "TryFrom Natural Int64"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9223372036854775807 ~?= Just 9223372036854775807
+                   , f 9223372036854775808 ~?= Nothing
+                   ]
+            , "TryFrom Natural Int"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       hush
+                           (Witch.tryFrom @Natural.Natural @Int
+                             (fromIntegral x)
+                           )
+                         ~?= Just x
+                   , let
+                       x =
+                         fromIntegral (maxBound :: Int) + 1 :: Natural.Natural
+                     in
+                       hush (Witch.tryFrom @Natural.Natural @Int x) ~?= Nothing
+                   ]
+            , "From Natural Integer"
+              ~: let f = Witch.from @Natural.Natural @Integer
+                 in [f 0 ~?= 0, f 9223372036854775808 ~?= 9223372036854775808]
+            , "TryFrom Natural Float"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Float
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   ]
+            , "TryFrom Natural Double"
+              ~: let f = hush . Witch.tryFrom @Natural.Natural @Double
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   ]
+
+    -- Float
+            , "TryFrom Float Int8"
+              ~: let f = hush . Witch.tryFrom @Float @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Int16"
+              ~: let f = hush . Witch.tryFrom @Float @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   , f (-32768) ~?= Just (-32768)
+                   , f (-32769) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Int32"
+              ~: let f = hush . Witch.tryFrom @Float @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Int64"
+              ~: let f = hush . Witch.tryFrom @Float @Int.Int64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Int"
+              ~: let f = hush . Witch.tryFrom @Float @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Integer"
+              ~: let f = hush . Witch.tryFrom @Float @Integer
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f (-16777216) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Word8"
+              ~: let f = hush . Witch.tryFrom @Float @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Word16"
+              ~: let f = hush . Witch.tryFrom @Float @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Word32"
+              ~: let f = hush . Witch.tryFrom @Float @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Word64"
+              ~: let f = hush . Witch.tryFrom @Float @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Word"
+              ~: let f = hush . Witch.tryFrom @Float @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Natural"
+              ~: let f = hush . Witch.tryFrom @Float @Natural.Natural
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 16777215 ~?= Just 16777215
+                   , f 16777216 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Float Rational"
+              ~: let f = hush . Witch.tryFrom @Float @Rational
+                 in
+                   [ f 0 ~?= Just 0
+                   , f (-0) ~?= Just 0
+                   , f 0.5 ~?= Just 0.5
+                   , f (-0.5) ~?= Just (-0.5)
+                   , f 16777215 ~?= Just 16777215
+                   , f (-16777215) ~?= Just (-16777215)
+                   , f 16777216 ~?= Just 16777216
+                   , f (-16777216) ~?= Just (-16777216)
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   , f 0.1 ~?= Just 0.1
+                   , f (-0.1) ~?= Just (-0.1)
+                   ]
+            , "From Float Double"
+              ~: let f = Witch.from @Float @Double
+                 in
+                   [ f 0 ~?= 0
+                   , f 0.5 ~?= 0.5
+                   , f (-0.5) ~?= (-0.5)
+                   , TestCase
+                     $ let x = f (0 / 0) in assertBool (show x) $ isNaN x
+                   , f (1 / 0) ~?= (1 / 0)
+                   , f (-1 / 0) ~?= (-1 / 0)
+                   ]
+
+    -- Double
+            , "TryFrom Double Int8"
+              ~: let f = hush . Witch.tryFrom @Double @Int.Int8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 127 ~?= Just 127
+                   , f 128 ~?= Nothing
+                   , f (-128) ~?= Just (-128)
+                   , f (-129) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Int16"
+              ~: let f = hush . Witch.tryFrom @Double @Int.Int16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 32767 ~?= Just 32767
+                   , f 32768 ~?= Nothing
+                   , f (-32768) ~?= Just (-32768)
+                   , f (-32769) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Int32"
+              ~: let f = hush . Witch.tryFrom @Double @Int.Int32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 2147483647 ~?= Just 2147483647
+                   , f 2147483648 ~?= Nothing
+                   , f (-2147483648) ~?= Just (-2147483648)
+                   , f (-2147483649) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Int64"
+              ~: let f = hush . Witch.tryFrom @Double @Int.Int64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   , f (-9007199254740991) ~?= Just (-9007199254740991)
+                   , f (-9007199254740992) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Int"
+              ~: let f = hush . Witch.tryFrom @Double @Int
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Int
+                     in
+                       if toInteger x >= 9007199254740991
+                         then f 9007199254740991 ~?= Just 9007199254740991
+                         else f (fromIntegral x) ~?= Just x
+                   , f 9007199254740992 ~?= Nothing
+                   , let x = minBound :: Int
+                     in
+                       if toInteger x <= (-9007199254740991)
+                         then f (-9007199254740991)
+                           ~?= Just (-9007199254740991)
+                         else f (fromIntegral x) ~?= Just x
+                   , f (-9007199254740992) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Integer"
+              ~: let f = hush . Witch.tryFrom @Double @Integer
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   , f (-9007199254740991) ~?= Just (-9007199254740991)
+                   , f (-9007199254740992) ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Word8"
+              ~: let f = hush . Witch.tryFrom @Double @Word.Word8
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 255 ~?= Just 255
+                   , f 256 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Word16"
+              ~: let f = hush . Witch.tryFrom @Double @Word.Word16
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 65535 ~?= Just 65535
+                   , f 65536 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Word32"
+              ~: let f = hush . Witch.tryFrom @Double @Word.Word32
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 4294967295 ~?= Just 4294967295
+                   , f 4294967296 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Word64"
+              ~: let f = hush . Witch.tryFrom @Double @Word.Word64
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Word"
+              ~: let f = hush . Witch.tryFrom @Double @Word
+                 in
+                   [ f 0 ~?= Just 0
+                   , let x = maxBound :: Word
+                     in
+                       if toInteger x >= 9007199254740991
+                         then f 9007199254740991 ~?= Just 9007199254740991
+                         else f (fromIntegral x) ~?= Just x
+                   , f 9007199254740992 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Natural"
+              ~: let f = hush . Witch.tryFrom @Double @Natural.Natural
+                 in
+                   [ f 0 ~?= Just 0
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f 9007199254740992 ~?= Nothing
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   ]
+            , "TryFrom Double Rational"
+              ~: let f = hush . Witch.tryFrom @Double @Rational
+                 in
+                   [ f 0 ~?= Just 0
+                   , f (-0) ~?= Just 0
+                   , f 0.5 ~?= Just 0.5
+                   , f (-0.5) ~?= Just (-0.5)
+                   , f 9007199254740991 ~?= Just 9007199254740991
+                   , f (-9007199254740991) ~?= Just (-9007199254740991)
+                   , f 9007199254740992 ~?= Just 9007199254740992
+                   , f (-9007199254740992) ~?= Just (-9007199254740992)
+                   , f (0 / 0) ~?= Nothing
+                   , f (1 / 0) ~?= Nothing
+                   , f (-1 / 0) ~?= Nothing
+                   , f 0.1 ~?= Just 0.1
+                   , f (-0.1) ~?= Just (-0.1)
+                   ]
+            , "From Double Float"
+              ~: let f = Witch.from @Double @Float
+                 in
+                   [ f 0 ~?= 0
+                   , f 0.5 ~?= 0.5
+                   , f (-0.5) ~?= (-0.5)
+                   , TestCase
+                     $ let x = f (0 / 0) in assertBool (show x) $ isNaN x
+                   , f (1 / 0) ~?= (1 / 0)
+                   , f (-1 / 0) ~?= (-1 / 0)
+                   ]
+
+    -- Ratio
+            , "From a (Ratio a)"
+              ~: let f = Witch.from @Int @(Ratio.Ratio Int)
+                 in [Witch.from @Integer @Rational 0 ~?= 0, f 0 ~?= 0]
+            , "TryFrom (Ratio a) a"
+              ~: let f = hush . Witch.tryFrom @(Ratio.Ratio Int) @Int
+                 in
+                   [ hush (Witch.tryFrom @Rational @Integer 0) ~?= Just 0
+                   , hush (Witch.tryFrom @Rational @Integer 0.5) ~?= Nothing
+                   , f 0 ~?= Just 0
+                   , f 0.5 ~?= Nothing
+                   ]
+            , "From Rational Float"
+              ~: let f = Witch.from @Rational @Float
+                 in
+                   [ f 0 ~?= 0
+                   , f 0.5 ~?= 0.5
+                   , f (-0.5) ~?= (-0.5)
+                   , f 0.1 ~?= 0.1
+                   , f (-0.1) ~?= (-0.1)
+                   ]
+            , "From Rational Double"
+              ~: let f = Witch.from @Rational @Double
+                 in
+                   [ f 0 ~?= 0
+                   , f 0.5 ~?= 0.5
+                   , f (-0.5) ~?= (-0.5)
+                   , f 0.1 ~?= 0.1
+                   , f (-0.1) ~?= (-0.1)
+                   ]
+            , "TryFrom Rational (Fixed a)"
+              ~: let f = hush . Witch.tryFrom @Rational @Fixed.Deci
+                 in
+                   [ hush (Witch.tryFrom @Rational @Fixed.Uni 1) ~?= Just 1
+                   , hush (Witch.tryFrom @Rational @Fixed.Uni 1.2) ~?= Nothing
+                   , f 0.1 ~?= Just 0.1
+                   , f 1.2 ~?= Just 1.2
+                   , f 12.3 ~?= Just 12.3
+                   , f 0.12 ~?= Nothing
+                   ]
+
+    -- Fixed
+            , "From Integer (Fixed a)"
+              ~: let f = Witch.from @Integer @Fixed.Deci
+                 in
+                   [ Witch.from @Integer @Fixed.Uni 1 ~?= 1
+                   , f 1 ~?= 0.1
+                   , f 10 ~?= 1
+                   , f 120 ~?= 12
+                   ]
+            , "From (Fixed a) Integer"
+              ~: let f = Witch.from @Fixed.Deci @Integer
+                 in
+                   [ Witch.from @Fixed.Uni @Integer 1 ~?= 1
+                   , f 0.1 ~?= 1
+                   , f 1 ~?= 10
+                   , f 12 ~?= 120
+                   ]
+            , "From (Fixed a) Rational"
+              ~: let f = Witch.from @Fixed.Deci @Rational
+                 in
+                   [ Witch.from @Fixed.Uni @Rational 1 ~?= 1
+                   , f 0.1 ~?= 0.1
+                   , f 1 ~?= 1
+                   , f 12 ~?= 12
+                   ]
+
+    -- Complex
+            , "From a (Complex a)"
+              ~: let f = Witch.from @Float @(Complex.Complex Float)
+                 in
+                   [ Witch.from @Double @(Complex.Complex Double) 1 ~?= 1
+                   , f 1 ~?= 1
+                   ]
+            , "TryFrom (Complex a) a"
+              ~: let f = hush . Witch.tryFrom @(Complex.Complex Float) @Float
+                 in
+                   [ hush (Witch.tryFrom @(Complex.Complex Double) @Double 1)
+                     ~?= Just 1
+                   , hush
+                       (Witch.tryFrom @(Complex.Complex Double) @Double
+                         (0 Complex.:+ 1)
+                       )
+                     ~?= Nothing
+                   , f 1 ~?= Just 1
+                   , f (0 Complex.:+ 1) ~?= Nothing
+                   ]
+
+    -- NonEmpty
+            , "TryFrom [a] (NonEmpty a)"
+              ~: let f = hush . Witch.tryFrom @[Int] @(NonEmpty.NonEmpty Int)
+                 in
+                   [ f [] ~?= Nothing
+                   , f [1] ~?= Just (1 NonEmpty.:| [])
+                   , f [1, 2] ~?= Just (1 NonEmpty.:| [2])
+                   ]
+            , "From (NonEmpty a) [a]"
+              ~: let f = Witch.from @(NonEmpty.NonEmpty Int) @[Int]
+                 in
+                   [ f (1 NonEmpty.:| []) ~?= [1]
+                   , f (1 NonEmpty.:| [2]) ~?= [1, 2]
+                   ]
+
+    -- Set
+            , "From [a] (Set a)"
+              ~: let f = Witch.from @[Char] @(Set.Set Char)
+                 in
+                   [ f [] ~?= Set.fromList []
+                   , f ['a'] ~?= Set.fromList ['a']
+                   , f ['a', 'b'] ~?= Set.fromList ['a', 'b']
+                   , f ['a', 'a'] ~?= Set.fromList ['a']
+                   ]
+            , "From (Set a) [a]"
+              ~: let f = Witch.from @(Set.Set Char) @[Char]
+                 in
+                   [ f (Set.fromList []) ~?= []
+                   , f (Set.fromList ['a']) ~?= ['a']
+                   , f (Set.fromList ['a', 'b']) ~?= ['a', 'b']
+                   ]
+
+    -- IntSet
+            , "From [Int] IntSet"
+              ~: let f = Witch.from @[Int] @IntSet.IntSet
+                 in
+                   [ f [] ~?= IntSet.fromList []
+                   , f [1] ~?= IntSet.fromList [1]
+                   , f [1, 2] ~?= IntSet.fromList [1, 2]
+                   ]
+            , "From IntSet [Int]"
+              ~: let f = Witch.from @IntSet.IntSet @[Int]
+                 in
+                   [ f (IntSet.fromList []) ~?= []
+                   , f (IntSet.fromList [1]) ~?= [1]
+                   , f (IntSet.fromList [1, 2]) ~?= [1, 2]
+                   ]
+
+    -- Map
+            , "From [(k, v)] (Map k v)"
+              ~: let f = Witch.from @[(Char, Int)] @(Map.Map Char Int)
+                 in
+                   [ f [] ~?= Map.empty
+                   , f [('a', 1)] ~?= Map.fromList [('a', 1)]
+                   , f [('a', 1), ('b', 2)]
+                     ~?= Map.fromList [('a', 1), ('b', 2)]
+                   , f [('a', 1), ('a', 2)] ~?= Map.fromList [('a', 2)]
+                   ]
+            , "From (Map k v) [(k, v)]"
+              ~: let f = Witch.from @(Map.Map Char Int) @[(Char, Int)]
+                 in
+                   [ f Map.empty ~?= []
+                   , f (Map.fromList [('a', 1)]) ~?= [('a', 1)]
+                   , f (Map.fromList [('a', 1), ('b', 2)])
+                     ~?= [('a', 1), ('b', 2)]
+                   ]
+
+    -- IntMap
+            , "From [(Int, v)] (IntMap v)"
+              ~: let f = Witch.from @[(Int, Char)] @(IntMap.IntMap Char)
+                 in
+                   [ f [] ~?= IntMap.fromList []
+                   , f [(1, 'a')] ~?= IntMap.fromList [(1, 'a')]
+                   , f [(1, 'a'), (2, 'b')]
+                     ~?= IntMap.fromList [(1, 'a'), (2, 'b')]
+                   , f [(1, 'a'), (1, 'b')] ~?= IntMap.fromList [(1, 'b')]
+                   ]
+            , "From (IntMap v) [(Int, v)]"
+              ~: let f = Witch.from @(IntMap.IntMap Char) @[(Int, Char)]
+                 in
+                   [ f (IntMap.fromList []) ~?= []
+                   , f (IntMap.fromList [(1, 'a')]) ~?= [(1, 'a')]
+                   , f (IntMap.fromList [(1, 'a'), (2, 'b')])
+                     ~?= [(1, 'a'), (2, 'b')]
+                   ]
+
+    -- Seq
+            , "From [a] (Seq a)"
+              ~: let f = Witch.from @[Int] @(Seq.Seq Int)
+                 in
+                   [ f [] ~?= Seq.fromList []
+                   , f [1] ~?= Seq.fromList [1]
+                   , f [1, 2] ~?= Seq.fromList [1, 2]
+                   ]
+            , "From (Seq a) [a]"
+              ~: let f = Witch.from @(Seq.Seq Int) @[Int]
+                 in
+                   [ f (Seq.fromList []) ~?= []
+                   , f (Seq.fromList [1]) ~?= [1]
+                   , f (Seq.fromList [1, 2]) ~?= [1, 2]
+                   ]
+
+    -- ByteString
+            , "From [Word8] ByteString"
+              ~: let f = Witch.from @[Word.Word8] @ByteString.ByteString
+                 in
+                   [ f [] ~?= ByteString.pack []
+                   , f [0x00] ~?= ByteString.pack [0x00]
+                   , f [0x0f, 0xf0] ~?= ByteString.pack [0x0f, 0xf0]
+                   ]
+            , "From ByteString [Word8]"
+              ~: let f = Witch.from @ByteString.ByteString @[Word.Word8]
+                 in
+                   [ f (ByteString.pack []) ~?= []
+                   , f (ByteString.pack [0x00]) ~?= [0x00]
+                   , f (ByteString.pack [0x0f, 0xf0]) ~?= [0x0f, 0xf0]
+                   ]
+            , "From ByteString LazyByteString"
+              ~: let
+                   f =
+                     Witch.from @ByteString.ByteString
+                       @LazyByteString.ByteString
+                 in
+                   [ f (ByteString.pack []) ~?= LazyByteString.pack []
+                   , f (ByteString.pack [0x00]) ~?= LazyByteString.pack [0x00]
+                   , f (ByteString.pack [0x0f, 0xf0])
+                     ~?= LazyByteString.pack [0x0f, 0xf0]
+                   ]
+            , "From ByteString ShortByteString"
+              ~: let
+                   f =
+                     Witch.from @ByteString.ByteString
+                       @ShortByteString.ShortByteString
+                 in
+                   [ f (ByteString.pack []) ~?= ShortByteString.pack []
+                   , f (ByteString.pack [0x00]) ~?= ShortByteString.pack [0x00]
+                   , f (ByteString.pack [0x0f, 0xf0])
+                     ~?= ShortByteString.pack [0x0f, 0xf0]
+                   ]
+            , "TryFrom ByteString Text"
+              ~: let
+                   f = hush . Witch.tryFrom @ByteString.ByteString @Text.Text
+                 in
+                   [ f (ByteString.pack []) ~?= Just (Text.pack "")
+                   , f (ByteString.pack [0x61]) ~?= Just (Text.pack "a")
+                   , f (ByteString.pack [0xff]) ~?= Nothing
+                   ]
+            , "TryFrom ByteString LazyText"
+              ~: let
+                   f =
+                     hush . Witch.tryFrom @ByteString.ByteString @LazyText.Text
+                 in
+                   [ f (ByteString.pack []) ~?= Just (LazyText.pack "")
+                   , f (ByteString.pack [0x61]) ~?= Just (LazyText.pack "a")
+                   , f (ByteString.pack [0xff]) ~?= Nothing
+                   ]
+            , "TryFrom ByteString String"
+              ~: let f = hush . Witch.tryFrom @ByteString.ByteString @String
+                 in
+                   [ f (ByteString.pack []) ~?= Just ""
+                   , f (ByteString.pack [0x61]) ~?= Just "a"
+                   , f (ByteString.pack [0xff]) ~?= Nothing
+                   ]
+
+    -- LazyByteString
+            , "From [Word8] LazyByteString"
+              ~: let f = Witch.from @[Word.Word8] @LazyByteString.ByteString
+                 in
+                   [ f [] ~?= LazyByteString.pack []
+                   , f [0x00] ~?= LazyByteString.pack [0x00]
+                   , f [0x0f, 0xf0] ~?= LazyByteString.pack [0x0f, 0xf0]
+                   ]
+            , "From LazyByteString [Word8]"
+              ~: let f = Witch.from @LazyByteString.ByteString @[Word.Word8]
+                 in
+                   [ f (LazyByteString.pack []) ~?= []
+                   , f (LazyByteString.pack [0x00]) ~?= [0x00]
+                   , f (LazyByteString.pack [0x0f, 0xf0]) ~?= [0x0f, 0xf0]
+                   ]
+            , "From LazyByteString ByteString"
+              ~: let
+                   f =
+                     Witch.from @LazyByteString.ByteString
+                       @ByteString.ByteString
+                 in
+                   [ f (LazyByteString.pack []) ~?= ByteString.pack []
+                   , f (LazyByteString.pack [0x00]) ~?= ByteString.pack [0x00]
+                   , f (LazyByteString.pack [0x0f, 0xf0])
+                     ~?= ByteString.pack [0x0f, 0xf0]
+                   ]
+            , "TryFrom LazyByteString LazyText"
+              ~: let
+                   f =
+                     hush
+                       . Witch.tryFrom @LazyByteString.ByteString
+                         @LazyText.Text
+                 in
+                   [ f (LazyByteString.pack []) ~?= Just (LazyText.pack "")
+                   , f (LazyByteString.pack [0x61])
+                     ~?= Just (LazyText.pack "a")
+                   , f (LazyByteString.pack [0xff]) ~?= Nothing
+                   ]
+            , "TryFrom LazyByteString Text"
+              ~: let
+                   f =
+                     hush . Witch.tryFrom @LazyByteString.ByteString @Text.Text
+                 in
+                   [ f (LazyByteString.pack []) ~?= Just (Text.pack "")
+                   , f (LazyByteString.pack [0x61]) ~?= Just (Text.pack "a")
+                   , f (LazyByteString.pack [0xff]) ~?= Nothing
+                   ]
+            , "TryFrom LazyByteString String"
+              ~: let
+                   f = hush . Witch.tryFrom @LazyByteString.ByteString @String
+                 in
+                   [ f (LazyByteString.pack []) ~?= Just ""
+                   , f (LazyByteString.pack [0x61]) ~?= Just "a"
+                   , f (LazyByteString.pack [0xff]) ~?= Nothing
+                   ]
+
+    -- ShortByteString
+            , "From [Word8] ShortByteString"
+              ~: let
+                   f =
+                     Witch.from @[Word.Word8] @ShortByteString.ShortByteString
+                 in
+                   [ f [] ~?= ShortByteString.pack []
+                   , f [0x00] ~?= ShortByteString.pack [0x00]
+                   , f [0x0f, 0xf0] ~?= ShortByteString.pack [0x0f, 0xf0]
+                   ]
+            , "From ShortByteString [Word8]"
+              ~: let
+                   f =
+                     Witch.from @ShortByteString.ShortByteString @[Word.Word8]
+                 in
+                   [ f (ShortByteString.pack []) ~?= []
+                   , f (ShortByteString.pack [0x00]) ~?= [0x00]
+                   , f (ShortByteString.pack [0x0f, 0xf0]) ~?= [0x0f, 0xf0]
+                   ]
+            , "From ShortByteString ByteString"
+              ~: let
+                   f =
+                     Witch.from @ShortByteString.ShortByteString
+                       @ByteString.ByteString
+                 in
+                   [ f (ShortByteString.pack []) ~?= ByteString.pack []
+                   , f (ShortByteString.pack [0x00]) ~?= ByteString.pack [0x00]
+                   , f (ShortByteString.pack [0x0f, 0xf0])
+                     ~?= ByteString.pack [0x0f, 0xf0]
+                   ]
+
+    -- Text
+            , "From Text LazyText"
+              ~: let f = Witch.from @Text.Text @LazyText.Text
+                 in
+                   [ f (Text.pack "") ~?= LazyText.pack ""
+                   , f (Text.pack "a") ~?= LazyText.pack "a"
+                   , f (Text.pack "ab") ~?= LazyText.pack "ab"
+                   ]
+            , "From Text ByteString"
+              ~: let f = Witch.from @Text.Text @ByteString.ByteString
+                 in
+                   [ f (Text.pack "") ~?= ByteString.pack []
+                   , f (Text.pack "a") ~?= ByteString.pack [0x61]
+                   ]
+            , "From Text LazyByteString"
+              ~: let f = Witch.from @Text.Text @LazyByteString.ByteString
+                 in
+                   [ f (Text.pack "") ~?= LazyByteString.pack []
+                   , f (Text.pack "a") ~?= LazyByteString.pack [0x61]
+                   ]
+
+    -- LazyText
+            , "From LazyText Text"
+              ~: let f = Witch.from @LazyText.Text @Text.Text
+                 in
+                   [ f (LazyText.pack "") ~?= Text.pack ""
+                   , f (LazyText.pack "a") ~?= Text.pack "a"
+                   , f (LazyText.pack "ab") ~?= Text.pack "ab"
+                   ]
+            , "From LazyText LazyByteString"
+              ~: let f = Witch.from @LazyText.Text @LazyByteString.ByteString
+                 in
+                   [ f (LazyText.pack "") ~?= LazyByteString.pack []
+                   , f (LazyText.pack "a") ~?= LazyByteString.pack [0x61]
+                   ]
+            , "From LazyText ByteString"
+              ~: let f = Witch.from @LazyText.Text @ByteString.ByteString
+                 in
+                   [ f (LazyText.pack "") ~?= ByteString.pack []
+                   , f (LazyText.pack "a") ~?= ByteString.pack [0x61]
+                   ]
+
+    -- String
+            , "From String Text"
+              ~: let f = Witch.from @String @Text.Text
+                 in
+                   [ f "" ~?= Text.pack ""
+                   , f "a" ~?= Text.pack "a"
+                   , f "ab" ~?= Text.pack "ab"
+                   ]
+            , "From Text String"
+              ~: let f = Witch.from @Text.Text @String
+                 in
+                   [ f (Text.pack "") ~?= ""
+                   , f (Text.pack "a") ~?= "a"
+                   , f (Text.pack "ab") ~?= "ab"
+                   ]
+            , "From String LazyText"
+              ~: let f = Witch.from @String @LazyText.Text
+                 in
+                   [ f "" ~?= LazyText.pack ""
+                   , f "a" ~?= LazyText.pack "a"
+                   , f "ab" ~?= LazyText.pack "ab"
+                   ]
+            , "From LazyText String"
+              ~: let f = Witch.from @LazyText.Text @String
+                 in
+                   [ f (LazyText.pack "") ~?= ""
+                   , f (LazyText.pack "a") ~?= "a"
+                   , f (LazyText.pack "ab") ~?= "ab"
+                   ]
+            , "From String ByteString"
+              ~: let f = Witch.from @String @ByteString.ByteString
+                 in
+                   [ f "" ~?= ByteString.pack []
+                   , f "a" ~?= ByteString.pack [0x61]
+                   ]
+            , "From String LazyByteString"
+              ~: let f = Witch.from @String @LazyByteString.ByteString
+                 in
+                   [ f "" ~?= LazyByteString.pack []
+                   , f "a" ~?= LazyByteString.pack [0x61]
+                   ]
+
+    -- Day
+            , "From Integer Day"
+              ~: let f = Witch.from @Integer @Time.Day
+                 in [f 0 ~?= Time.ModifiedJulianDay 0]
+            , "From Day Integer"
+              ~: let f = Witch.from @Time.Day @Integer
+                 in [f (Time.ModifiedJulianDay 0) ~?= 0]
+
+    -- DayOfWeek
+            , "From Day DayOfWeek"
+              ~: let f = Witch.from @Time.Day @Time.DayOfWeek
+                 in [f (Time.ModifiedJulianDay 0) ~?= Time.Wednesday]
+
+    -- UniversalTime
+            , "From Rational UniversalTime"
+              ~: let f = Witch.from @Rational @Time.UniversalTime
+                 in [f 0 ~?= Time.ModJulianDate 0]
+            , "From UniversalTime Rational"
+              ~: let f = Witch.from @Time.UniversalTime @Rational
+                 in [f (Time.ModJulianDate 0) ~?= 0]
+
+    -- DiffTime
+            , "From Pico DiffTime"
+              ~: let f = Witch.from @Fixed.Pico @Time.DiffTime in [f 0 ~?= 0]
+            , "From DiffTime Pico"
+              ~: let f = Witch.from @Time.DiffTime @Fixed.Pico in [f 0 ~?= 0]
+
+    -- NominalDiffTime
+            , "From Pico NominalDiffTime"
+              ~: let f = Witch.from @Fixed.Pico @Time.NominalDiffTime
+                 in [f 0 ~?= 0]
+            , "From NominalDiffTime Pico"
+              ~: let f = Witch.from @Time.NominalDiffTime @Fixed.Pico
+                 in [f 0 ~?= 0]
+
+    -- POSIXTime
+            , "From SystemTime POSIXTime"
+              ~: let f = Witch.from @Time.SystemTime @Time.POSIXTime
+                 in [f (Time.MkSystemTime 0 0) ~?= 0]
+            , "From UTCTime POSIXTime"
+              ~: let f = Witch.from @Time.UTCTime @Time.POSIXTime
+                 in [f unixEpoch ~?= 0]
+            , "From POSIXTime UTCTime"
+              ~: let f = Witch.from @Time.POSIXTime @Time.UTCTime
+                 in [f 0 ~?= unixEpoch]
+
+    -- SystemTime
+            , "From UTCTime SystemTime"
+              ~: let f = Witch.from @Time.UTCTime @Time.SystemTime
+                 in [f unixEpoch ~?= Time.MkSystemTime 0 0]
+            , "From SystemTime AbsoluteTime"
+              ~: let f = Witch.from @Time.SystemTime @Time.AbsoluteTime
+                 in [f (Time.MkSystemTime (-3506716800) 0) ~?= Time.taiEpoch]
+            , "From SystemTime UTCTime"
+              ~: let f = Witch.from @Time.SystemTime @Time.UTCTime
+                 in [f (Time.MkSystemTime 0 0) ~?= unixEpoch]
+
+    -- TimeOfDay
+            , "From DiffTime TimeOfDay"
+              ~: let f = Witch.from @Time.DiffTime @Time.TimeOfDay
+                 in [f 0 ~?= Time.TimeOfDay 0 0 0]
+            , "From Rational TimeOfDay"
+              ~: let f = Witch.from @Rational @Time.TimeOfDay
+                 in [f 0 ~?= Time.TimeOfDay 0 0 0]
+            , "From TimeOfDay DiffTime"
+              ~: let f = Witch.from @Time.TimeOfDay @Time.DiffTime
+                 in [f (Time.TimeOfDay 0 0 0) ~?= 0]
+            , "From TimeOfDay Rational"
+              ~: let f = Witch.from @Time.TimeOfDay @Rational
+                 in [f (Time.TimeOfDay 0 0 0) ~?= 0]
+
+    -- CalendarDiffTime
+            , "From CalendarDiffDays CalendarDiffTime"
+              ~: let
+                   f =
+                     Witch.from @Time.CalendarDiffDays @Time.CalendarDiffTime
+                 in
+                   [ f (Time.CalendarDiffDays 0 0)
+                       ~?= Time.CalendarDiffTime 0 0
+                   ]
+            , "From NominalDiffTime CalendarDiffTime"
+              ~: let
+                   f = Witch.from @Time.NominalDiffTime @Time.CalendarDiffTime
+                 in [f 0 ~?= Time.CalendarDiffTime 0 0]
+
+    -- ZonedTime
+            , "From ZonedTime UTCTime"
+              ~: let f = Witch.from @Time.ZonedTime @Time.UTCTime
+                 in
+                   [ f
+                         (Time.ZonedTime
+                           (Time.LocalTime
+                             (Time.ModifiedJulianDay 0)
+                             (Time.TimeOfDay 0 0 0)
+                           )
+                           Time.utc
+                         )
+                       ~?= Time.UTCTime (Time.ModifiedJulianDay 0) 0
+                   ]
+            ]
+       ]
+
+unixEpoch :: Time.UTCTime
+unixEpoch = Time.UTCTime (Time.ModifiedJulianDay 40587) 0
+
+hush :: Either x a -> Maybe a
+hush = either (const Nothing) Just
+
+newtype Age
+  = Age Int.Int8
+  deriving (Eq, Show)
+
+instance Witch.From Age Int.Int8
+
+instance Witch.From Int.Int8 Age
diff --git a/src/ghc-8.10/Witch/Lift.hs b/src/ghc-8.10/Witch/Lift.hs
deleted file mode 100644
--- a/src/ghc-8.10/Witch/Lift.hs
+++ /dev/null
@@ -1,48 +0,0 @@
-{-# LANGUAGE ExplicitForAll #-}
-
-module Witch.Lift where
-
-import qualified Data.Typeable as Typeable
-import qualified Language.Haskell.TH.Syntax as TH
-import qualified Witch.TryFrom as TryFrom
-import qualified Witch.Utility as Utility
-
--- | This is like 'Utility.unsafeFrom' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeFrom @s "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedFrom @s "some literal")
-liftedFrom
-  :: forall source target
-   . ( TryFrom.TryFrom source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> TH.Q (TH.TExp target)
-liftedFrom = TH.liftTyped . Utility.unsafeFrom
-
--- | This is like 'Utility.unsafeInto' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeInto @t "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedInto @t "some literal")
-liftedInto
-  :: forall target source
-   . ( TryFrom.TryFrom source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> TH.Q (TH.TExp target)
-liftedInto = liftedFrom
diff --git a/src/ghc-8.8/Witch/Lift.hs b/src/ghc-8.8/Witch/Lift.hs
deleted file mode 100644
--- a/src/ghc-8.8/Witch/Lift.hs
+++ /dev/null
@@ -1,48 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Witch.Lift where
-
-import qualified Data.Typeable as Typeable
-import qualified Language.Haskell.TH.Syntax as TH
-import qualified Witch.TryFrom as TryFrom
-import qualified Witch.Utility as Utility
-
--- | This is like 'Utility.unsafeFrom' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeFrom @s "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedFrom @s "some literal")
-liftedFrom
-  :: forall source target
-   . ( TryFrom.TryFrom source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> TH.Q (TH.TExp target)
-liftedFrom s = TH.unsafeTExpCoerce $ TH.lift (Utility.unsafeFrom s :: target)
-
--- | This is like 'Utility.unsafeInto' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeInto @t "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedInto @t "some literal")
-liftedInto
-  :: forall target source
-   . ( TryFrom.TryFrom source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> TH.Q (TH.TExp target)
-liftedInto = liftedFrom
diff --git a/src/ghc-9.0/Witch/Lift.hs b/src/ghc-9.0/Witch/Lift.hs
deleted file mode 100644
--- a/src/ghc-9.0/Witch/Lift.hs
+++ /dev/null
@@ -1,50 +0,0 @@
-{-# LANGUAGE ExplicitForAll #-}
-
-module Witch.Lift where
-
-import qualified Data.Typeable as Typeable
-import qualified Language.Haskell.TH.Syntax as TH
-import qualified Witch.TryFrom as TryFrom
-import qualified Witch.Utility as Utility
-
--- | This is like 'Utility.unsafeFrom' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeFrom @s "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedFrom @s "some literal")
-liftedFrom
-  :: forall source target m
-   . ( TryFrom.TryFrom source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     , TH.Quote m
-     )
-  => source
-  -> TH.Code m target
-liftedFrom = TH.liftTyped . Utility.unsafeFrom
-
--- | This is like 'Utility.unsafeInto' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeInto @t "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedInto @t "some literal")
-liftedInto
-  :: forall target source m
-   . ( TryFrom.TryFrom source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     , TH.Quote m
-     )
-  => source
-  -> TH.Code m target
-liftedInto = liftedFrom
diff --git a/src/lib/Witch.hs b/src/lib/Witch.hs
deleted file mode 100644
--- a/src/lib/Witch.hs
+++ /dev/null
@@ -1,258 +0,0 @@
--- | The Witch package is a library that allows you to confidently convert
--- values between various types. This module exports everything you need to
--- perform conversions or define your own. It is designed to be imported
--- unqualified, so getting started is as easy as:
---
--- >>> import Witch
---
--- In typical usage, the functions that you will use most often are
--- 'Witch.Utility.into' for conversions that always succeed and
--- 'Witch.Utility.tryInto' for conversions that sometimes fail.
-module Witch
-  ( -- * Type classes
-
-  -- ** From
-    Witch.From.From(from)
-  , Witch.Utility.into
-
-  -- ** TryFrom
-  , Witch.TryFrom.TryFrom(tryFrom)
-  , Witch.Utility.tryInto
-
-  -- * Data types
-  , Witch.TryFromException.TryFromException(..)
-
-  -- * Utilities
-  , Witch.Utility.as
-  , Witch.Utility.over
-  , Witch.Utility.via
-  , Witch.Utility.tryVia
-  , Witch.Utility.maybeTryFrom
-  , Witch.Utility.eitherTryFrom
-
-  -- ** Unsafe
-  -- | These functions should only be used in two circumstances: When you know
-  -- a conversion is safe even though you can't prove it to the compiler, and
-  -- when you're alright with your program crashing if the conversion fails.
-  -- In all other cases you should prefer the normal conversion functions like
-  -- 'Witch.TryFrom.tryFrom'. And if you're converting a literal value,
-  -- consider using the Template Haskell conversion functions like
-  -- 'Witch.Lift.liftedFrom'.
-  , Witch.Utility.unsafeFrom
-  , Witch.Utility.unsafeInto
-
-  -- ** Template Haskell
-  -- | This library uses /typed/ Template Haskell, which may be a little
-  -- different than what you're used to. Normally Template Haskell uses the
-  -- @$(...)@ syntax for splicing in things to run at compile time. The typed
-  -- variant uses the @$$(...)@ syntax for splices, doubling up on the dollar
-  -- signs. Other than that, using typed Template Haskell should be pretty
-  -- much the same as using regular Template Haskell.
-  , Witch.Lift.liftedFrom
-  , Witch.Lift.liftedInto
-
-  -- * Notes
-
-  -- ** Motivation
-  -- | Haskell provides many ways to convert between common types, and core
-  -- libraries add even more. It can be challenging to know which function to
-  -- use when converting from some source type @a@ to some target type @b@. It
-  -- can be even harder to know if that conversion is safe or if there are any
-  -- pitfalls to watch out for.
-  --
-  -- This library tries to address that problem by providing a common
-  -- interface for converting between types. The 'Witch.From.From' type class
-  -- is for conversions that cannot fail, and the 'Witch.TryFrom.TryFrom' type
-  -- class is for conversions that can fail. These type classes are inspired
-  -- by the [@From@](https://doc.rust-lang.org/std/convert/trait.From.html)
-  -- trait in Rust.
-
-  -- ** Type applications
-  -- | Although you can use this library without the [@TypeApplications@](https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/exts/type_applications.html)
-  -- language extension, the extension is strongly recommended. Since most
-  -- functions provided by this library are polymorphic in at least one type
-  -- variable, it's easy to use them in a situation that would be ambiguous.
-  -- Normally you could resolve the ambiguity with an explicit type signature,
-  -- but type applications are much more ergonomic. For example:
-  --
-  -- > -- Avoid this:
-  -- > f . (from :: Int8 -> Int16) . g
-  -- >
-  -- > -- Prefer this:
-  -- > f . from @Int8 @Int16 . g
-  --
-  -- Most functions in this library have two versions with their type
-  -- variables in opposite orders. That's because usually one side of the
-  -- conversion or the other already has its type inferred by context. In
-  -- those situations it makes sense to only provide one type argument.
-  --
-  -- > -- Avoid this: (assuming f :: Int16 -> ...)
-  -- > f $ from @Int8 @Int16 0
-  -- >
-  -- > -- Prefer this:
-  -- > f $ from @Int8 0
-  --
-  -- > -- Avoid this: (assuming x :: Int8)
-  -- > g $ from @Int8 @Int16 x
-  -- >
-  -- > -- Prefer this:
-  -- > g $ into @Int16 x
-
-  -- ** Alternatives
-  -- | Many Haskell libraries already provide similar functionality. How is
-  -- this library different?
-  --
-  -- - [@Coercible@](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Coerce.html#t:Coercible):
-  --   This type class is solved by the compiler, but it only works for types
-  --   that have the same runtime representation. This is very convenient for
-  --   @newtype@s, but it does not work for converting between arbitrary types
-  --   like @Int8@ and @Int16@.
-  --
-  -- - [@Convertible@](https://hackage.haskell.org/package/convertible-1.1.1.0/docs/Data-Convertible-Base.html#t:Convertible):
-  --   This popular conversion type class is similar to what this library
-  --   provides. The main difference is that it does not differentiate between
-  --   conversions that can fail and those that cannot.
-  --
-  -- - [@From@](https://hackage.haskell.org/package/basement-0.0.11/docs/Basement-From.html#t:From):
-  --   This type class is almost identical to what this library provides.
-  --   Unfortunately it is part of the @basement@ package, which is an
-  --   alternative standard library that some people may not want to depend
-  --   on.
-  --
-  -- - [@Inj@](https://hackage.haskell.org/package/inj-1.0/docs/Inj.html#t:Inj):
-  --   This type class requires instances to be an injection, which means that
-  --   no two input values should map to the same output. That restriction
-  --   prohibits many useful instances. Also many instances throw impure
-  --   exceptions.
-  --
-  -- In addition to those general-purpose type classes, there are many
-  -- alternatives for more specific conversions. How does this library compare
-  -- to those?
-  --
-  -- - Monomorphic conversion functions like [@Data.Text.pack@](https://hackage.haskell.org/package/text-1.2.4.1/docs/Data-Text.html#v:pack)
-  --   are explicit but not necessarily convenient. It can be tedious to
-  --   manage the imports necessary to use the functions. And if you want to
-  --   put them in a custom prelude, you will have to come up with your own
-  --   names.
-  --
-  -- - Polymorphic conversion methods like 'toEnum' are more convenient but
-  --   may have unwanted semantics or runtime behavior. For example the 'Enum'
-  --   type class is more or less tied to the 'Int' data type and frequently
-  --   throws impure exceptions.
-  --
-  -- - Polymorphic conversion functions like 'fromIntegral' are very
-  --   convenient. Unfortunately it can be challenging to know which types
-  --   have the instances necessary to make the conversion possible. And even
-  --   if the conversion is possible, is it safe? For example converting a
-  --   negative 'Int' into a 'Word' will overflow, which may be surprising.
-
-  -- ** Instances
-  -- | When should you add a 'Witch.From.From' (or 'Witch.TryFrom.TryFrom')
-  -- instance for some pair of types? This is a surprisingly tricky question
-  -- to answer precisely. Instances are driven more by guidelines than rules.
-  --
-  -- - Conversions must not throw impure exceptions. This means no 'undefined'
-  --   or anything equivalent to it.
-  --
-  -- - Conversions should be unambiguous. If there are multiple reasonable
-  --   ways to convert from @a@ to @b@, then you probably should not add a
-  --   'Witch.From.From' instance for them.
-  --
-  -- - Conversions should be lossless. If you have @From a b@ then no two @a@
-  --   values should be converted to the same @b@ value.
-  --
-  --     - Some conversions necessarily lose information, like converting from
-  --       a list into a set.
-  --
-  -- - If you have both @From a b@ and @From b a@, then
-  --   @from \@b \@a . from \@a \@b@ should be the same as 'id'. In other
-  --   words, @a@ and @b@ are isomorphic.
-  --
-  --     - This often true, but not always. For example, converting a list
-  --       into a set will remove duplicates. And then converting back into a
-  --       list will put the elements in ascending order.
-  --
-  -- - If you have both @From a b@ and @From b c@, then you could also have
-  --   @From a c@ and it should be the same as @from \@b \@c . from \@a \@b@.
-  --   In other words, @From@ is transitive.
-  --
-  --     - This is not always true. For example an @Int8@ may be represented
-  --       as a number in JSON, whereas an @Int64@ might be represented as a
-  --       string. That means @into \@JSON (into \@Int64 int8)@ would not be
-  --       the same as @into \@JSON int8@.
-  --
-  -- - You should not have both a @From@ instance and a @TryFrom@ instance for
-  --   the same pair of types.
-  --
-  -- - If you have a @From@ or @TryFrom@ instance for a pair of types, then
-  --   you should probably have a @From@ or @TryFrom@ instance for the same
-  --   pair of types but in the opposite direction. In other words if you have
-  --   @From a b@ then you should have @From b a@ or @TryFrom b a@.
-  --
-  -- In general if @s@ /is/ a @t@, then you should add a 'Witch.From.From'
-  -- instance for it. But if @s@ merely /can be/ a @t@, then you could add a
-  -- 'Witch.TryFrom.TryFrom' instance for it. And if it is technically
-  -- possible to convert from @s@ to @t@ but there are a lot of caveats, you
-  -- probably should not write any instances at all.
-
-  -- ** Laws
-  -- | As the previous section notes, there aren't any cut and dried laws for
-  -- the @From@ and @TryFrom@ type classes. However it can be useful to
-  -- consider the following equations for guiding instances:
-  --
-  -- > -- same strictness
-  -- > seq (from @a @b x) y = seq x y
-  -- > seq (tryFrom @a @b x) y = seq x y
-  --
-  -- > -- round trip
-  -- > from @b @a (from @a @b x) = x
-  --
-  -- > -- transitive
-  -- > from @b @c (from @a @b x) = from @a @c x
-  -- > tryFrom @b @a (from @a @b x) = Right x
-  -- > if isRight (tryFrom @a @b x) then
-  -- >   fmap (from @b @a) (tryFrom @a @b x) = Right x
-  -- > if isRight (tryFrom @a @b x) then do
-  -- >   fmap (tryFrom @b @a) (tryFrom @a @b x) = Right (Right x)
-
-  -- ** Integral types
-  -- | There are a lot of types that represent various different ranges of
-  -- integers, and Witch may not provide the instances you want. In particular
-  -- it does not provide a total way to convert from an @Int32@ into an @Int@.
-  -- Why is that?
-  --
-  -- The Haskell Language Report only demands that @Int@s have at least 30
-  -- bits of precision. That means a reasonable Haskell implementation could
-  -- have an @Int@ type that's smaller than the @Int32@ type.
-  --
-  -- However in practice everyone uses the same Haskell implementation: GHC.
-  -- And with GHC the @Int@ type always has 32 bits of precision, even on
-  -- 32-bit architectures. So for almost everybody, it's probably safe to use
-  -- @unsafeFrom \@Int32 \@Int@. Similarly most software these days runs on
-  -- machines with 64-bit architectures. That means it's also probably safe
-  -- for you to use @unsafeFrom \@Int64 \@Int@.
-  --
-  -- All of the above also applies for @Word@, @Word32@, and @Word64@.
-
-  -- ** Downsides
-  -- | As the author of this library, I obviously think that everyone should
-  -- use it because it's the greatest thing since sliced bread. But nothing is
-  -- perfect, so what are some downsides to this library?
-  --
-  -- - More specific type classes are often better. For example, @IsString s@
-  --   is more useful that @From String s@. The former says that the type @s@
-  --   is the same as a string literal, but the latter just says you can
-  --   produce a value of type @s@ when given a string.
-  --
-  -- - The @From@ type class works great for specific pairs of types, but can
-  --   get confusing when it's polymorphic. For example if you have some
-  --   function with a @From s t@ constraint, that doesn't really tell you
-  --   anything about what it's doing.
-  ) where
-
-import qualified Witch.From
-import Witch.Instances ()
-import qualified Witch.Lift
-import qualified Witch.TryFrom
-import qualified Witch.TryFromException
-import qualified Witch.Utility
diff --git a/src/lib/Witch/From.hs b/src/lib/Witch/From.hs
deleted file mode 100644
--- a/src/lib/Witch/From.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-{-# LANGUAGE DefaultSignatures #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module Witch.From where
-
-import qualified Data.Coerce as Coerce
-
--- | This type class is for converting values from some @source@ type into
--- some other @target@ type. The constraint @'From' source target@ means that
--- you can convert from a value of type @source@ into a value of type
--- @target@.
---
--- This type class is for conversions that always succeed. If your conversion
--- sometimes fails, consider implementing @TryFrom@ instead.
-class From source target where
-  -- | This method implements the conversion of a value between types. At call
-  -- sites you may prefer to use @into@ instead.
-  --
-  -- > -- Avoid this:
-  -- > from (x :: s)
-  -- >
-  -- > -- Prefer this:
-  -- > from @s x
-  --
-  -- The default implementation of this method simply calls 'Coerce.coerce',
-  -- which works for types that have the same runtime representation. This
-  -- means that for @newtype@s you do not need to implement this method at
-  -- all. For example:
-  --
-  -- >>> newtype Name = Name String
-  -- >>> instance From Name String
-  -- >>> instance From String Name
-  from :: source -> target
-
-  default from :: Coerce.Coercible source target => source -> target
-  from = Coerce.coerce
diff --git a/src/lib/Witch/Instances.hs b/src/lib/Witch/Instances.hs
deleted file mode 100644
--- a/src/lib/Witch/Instances.hs
+++ /dev/null
@@ -1,1291 +0,0 @@
-{-# OPTIONS_GHC -Wno-orphans #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
-
-module Witch.Instances where
-
-import qualified Control.Exception as Exception
-import qualified Data.Bits as Bits
-import qualified Data.ByteString as ByteString
-import qualified Data.ByteString.Lazy as LazyByteString
-import qualified Data.ByteString.Short as ShortByteString
-import qualified Data.Complex as Complex
-import qualified Data.Fixed as Fixed
-import qualified Data.Foldable as Foldable
-import qualified Data.Int as Int
-import qualified Data.IntMap as IntMap
-import qualified Data.IntSet as IntSet
-import qualified Data.List as List
-import qualified Data.List.NonEmpty as NonEmpty
-import qualified Data.Map as Map
-import qualified Data.Ratio as Ratio
-import qualified Data.Sequence as Seq
-import qualified Data.Set as Set
-import qualified Data.Text as Text
-import qualified Data.Text.Encoding as Text
-import qualified Data.Text.Lazy as LazyText
-import qualified Data.Text.Lazy.Encoding as LazyText
-import qualified Data.Time as Time
-import qualified Data.Time.Clock.POSIX as Time
-import qualified Data.Time.Clock.System as Time
-import qualified Data.Time.Clock.TAI as Time
-import qualified Data.Word as Word
-import qualified GHC.Float as Float
-import qualified Numeric
-import qualified Numeric.Natural as Natural
-import qualified Witch.From as From
-import qualified Witch.TryFrom as TryFrom
-import qualified Witch.TryFromException as TryFromException
-import qualified Witch.Utility as Utility
-
--- | Uses 'id'.
-instance From.From a a where
-  from = id
-
--- Int8
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Int.Int16 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Int.Int32 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Int where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Integer where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int8 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int8 Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int8 Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int8 Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int8 Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral' when the input is not negative.
-instance TryFrom.TryFrom Int.Int8 Natural.Natural where
-  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Float where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int8 Double where
-  from = fromIntegral
-
--- Int16
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int16 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int16 Int.Int32 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int16 Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int16 Int where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int16 Integer where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int16 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int16 Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int16 Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int16 Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int16 Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral' when the input is not negative.
-instance TryFrom.TryFrom Int.Int16 Natural.Natural where
-  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int16 Float where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int16 Double where
-  from = fromIntegral
-
--- Int32
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int32 Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int32 Integer where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int32 Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral' when the input is not negative.
-instance TryFrom.TryFrom Int.Int32 Natural.Natural where
-  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
-
--- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
--- inclusive.
-instance TryFrom.TryFrom Int.Int32 Float where
-  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
-    then Left Exception.Underflow
-    else if s > maxFloat
-      then Left Exception.Overflow
-      else Right $ fromIntegral s
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int32 Double where
-  from = fromIntegral
-
--- Int64
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Int.Int64 Integer where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int.Int64 Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral' when the input is not negative.
-instance TryFrom.TryFrom Int.Int64 Natural.Natural where
-  -- This should use @eitherTryFrom fromNonNegativeIntegral@, but that causes
-  -- a bug in GHC 9.0.1.
-  -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html
-  tryFrom =
-    Utility.eitherTryFrom $ \s -> TryFrom.tryFrom (From.from s :: Integer)
-
--- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
--- inclusive.
-instance TryFrom.TryFrom Int.Int64 Float where
-  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
-    then Left Exception.Underflow
-    else if s > maxFloat
-      then Left Exception.Overflow
-      else Right $ fromIntegral s
-
--- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
--- 9,007,199,254,740,991 inclusive.
-instance TryFrom.TryFrom Int.Int64 Double where
-  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxDouble
-    then Left Exception.Underflow
-    else if s > maxDouble
-      then Left Exception.Overflow
-      else Right $ fromIntegral s
-
--- Int
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Int Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Int Integer where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Int Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral' when the input is not negative.
-instance TryFrom.TryFrom Int Natural.Natural where
-  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
-
--- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
--- inclusive.
-instance TryFrom.TryFrom Int Float where
-  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
-    then Left Exception.Underflow
-    else if s > maxFloat
-      then Left Exception.Overflow
-      else Right $ fromIntegral s
-
--- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
--- 9,007,199,254,740,991 inclusive.
-instance TryFrom.TryFrom Int Double where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if toInteger (maxBound :: Int) <= maxDouble
-      then Right $ fromIntegral s
-      else if s < -maxDouble
-        then Left Exception.Underflow
-        else if s > maxDouble
-          then Left Exception.Overflow
-          else Right $ fromIntegral s
-
--- Integer
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Int.Int64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Integer Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromInteger' when the input is not negative.
-instance TryFrom.TryFrom Integer Natural.Natural where
-  -- This should use @eitherTryFrom fromNonNegativeIntegral@, but that causes
-  -- a bug in GHC 9.0.1. By inlining @fromNonNegativeIntegral@ and replacing
-  -- @fromIntegral@ with @fromInteger@, we can work around the bug.
-  -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html
-  tryFrom = Utility.eitherTryFrom
-    $ \s -> if s < 0 then Left Exception.Underflow else Right $ fromInteger s
-
--- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
--- inclusive.
-instance TryFrom.TryFrom Integer Float where
-  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat
-    then Left Exception.Underflow
-    else if s > maxFloat
-      then Left Exception.Overflow
-      else Right $ fromIntegral s
-
--- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
--- 9,007,199,254,740,991 inclusive.
-instance TryFrom.TryFrom Integer Double where
-  tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxDouble
-    then Left Exception.Underflow
-    else if s > maxDouble
-      then Left Exception.Overflow
-      else Right $ fromIntegral s
-
--- Word8
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Word.Word16 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Word.Word32 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Word.Word64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Word where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Natural.Natural where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word8 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Int.Int16 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Int.Int32 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Int where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Integer where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Float where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word8 Double where
-  from = fromIntegral
-
--- Word16
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word16 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Word.Word32 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Word.Word64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Word where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Natural.Natural where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word16 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word16 Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Int.Int32 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Int where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Integer where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Float where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word16 Double where
-  from = fromIntegral
-
--- Word32
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word32 Word.Word64 where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word32 Natural.Natural where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word32 Int.Int64 where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word32 Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word32 Integer where
-  from = fromIntegral
-
--- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
-instance TryFrom.TryFrom Word.Word32 Float where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word32 Double where
-  from = fromIntegral
-
--- Word64
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word64 Natural.Natural where
-  -- This should use @fromIntegral@, but that causes a bug in GHC 9.0.1.
-  -- https://mail.haskell.org/pipermail/haskell-cafe/2021-March/133540.html
-  from s = Utility.unsafeFrom (From.from s :: Integer)
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Int.Int64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word.Word64 Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word.Word64 Integer where
-  from = fromIntegral
-
--- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
-instance TryFrom.TryFrom Word.Word64 Float where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
-
--- | Uses 'fromIntegral' when the input is less than or equal to
--- 9,007,199,254,740,991.
-instance TryFrom.TryFrom Word.Word64 Double where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if s <= maxDouble then Right $ fromIntegral s else Left Exception.Overflow
-
--- Word
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word Word.Word64 where
-  from = fromIntegral
-
--- | Uses 'fromIntegral'.
-instance From.From Word Natural.Natural where
-  from = fromIntegral
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Int.Int64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Word Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Word Integer where
-  from = fromIntegral
-
--- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
-instance TryFrom.TryFrom Word Float where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
-
--- | Uses 'fromIntegral' when the input is less than or equal to
--- 9,007,199,254,740,991.
-instance TryFrom.TryFrom Word Double where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if (toInteger (maxBound :: Word) <= maxDouble) || (s <= maxDouble)
-      then Right $ fromIntegral s
-      else Left Exception.Overflow
-
--- Natural
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Word.Word8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Word.Word16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Word.Word32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Word.Word64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Word where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Int.Int8 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Int.Int16 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Int.Int32 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Int.Int64 where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'Bits.toIntegralSized'.
-instance TryFrom.TryFrom Natural.Natural Int where
-  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
-
--- | Uses 'fromIntegral'.
-instance From.From Natural.Natural Integer where
-  from = fromIntegral
-
--- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
-instance TryFrom.TryFrom Natural.Natural Float where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow
-
--- | Uses 'fromIntegral' when the input is less than or equal to
--- 9,007,199,254,740,991.
-instance TryFrom.TryFrom Natural.Natural Double where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    if s <= maxDouble then Right $ fromIntegral s else Left Exception.Overflow
-
--- Float
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Int.Int8 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Int.Int16 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Int.Int32 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Int.Int64 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Int where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Rational' when the input is between -16,777,215 and
--- 16,777,215 inclusive.
-instance TryFrom.TryFrom Float Integer where
-  tryFrom = Utility.eitherTryFrom $ \s -> case Utility.tryVia @Rational s of
-    Left e -> Left $ Exception.toException e
-    Right t
-      | t < -maxFloat -> Left $ Exception.toException Exception.Underflow
-      | t > maxFloat -> Left $ Exception.toException Exception.Overflow
-      | otherwise -> Right t
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Word.Word8 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Word.Word16 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Word.Word32 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Word.Word64 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Word where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Float Natural.Natural where
-  tryFrom = Utility.tryVia @Integer
-
--- | Uses 'Numeric.floatToDigits' when the input is not NaN or infinity.
-instance TryFrom.TryFrom Float Rational where
-  tryFrom = Utility.eitherTryFrom realFloatToRational
-
--- | Uses 'Float.float2Double'.
-instance From.From Float Double where
-  from = Float.float2Double
-
--- Double
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Int.Int8 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Int.Int16 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Int.Int32 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Int.Int64 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Int where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Rational' when the input is between -9,007,199,254,740,991
--- and 9,007,199,254,740,991 inclusive.
-instance TryFrom.TryFrom Double Integer where
-  tryFrom = Utility.eitherTryFrom $ \s -> case Utility.tryVia @Rational s of
-    Left e -> Left $ Exception.toException e
-    Right t
-      | t < -maxDouble -> Left $ Exception.toException Exception.Underflow
-      | t > maxDouble -> Left $ Exception.toException Exception.Overflow
-      | otherwise -> Right t
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Word.Word8 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Word.Word16 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Word.Word32 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Word.Word64 where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Word where
-  tryFrom = Utility.tryVia @Integer
-
--- | Converts via 'Integer'.
-instance TryFrom.TryFrom Double Natural.Natural where
-  tryFrom = Utility.tryVia @Integer
-
--- | Uses 'Numeric.floatToDigits' when the input is not NaN or infinity.
-instance TryFrom.TryFrom Double Rational where
-  tryFrom = Utility.eitherTryFrom realFloatToRational
-
--- | Uses 'Float.double2Float'. This necessarily loses some precision.
-instance From.From Double Float where
-  from = Float.double2Float
-
--- Ratio
-
--- | Uses '(Ratio.%)' with a denominator of 1.
-instance Integral a => From.From a (Ratio.Ratio a) where
-  from = (Ratio.% 1)
-
--- | Uses 'Ratio.numerator' when the denominator is 1.
-instance (Eq a, Num a) => TryFrom.TryFrom (Ratio.Ratio a) a where
-  tryFrom = Utility.eitherTryFrom $ \s -> if Ratio.denominator s == 1
-    then Right $ Ratio.numerator s
-    else Left Exception.LossOfPrecision
-
--- | Uses 'fromRational'. This necessarily loses some precision.
-instance From.From Rational Float where
-  from = fromRational
-
--- | Uses 'fromRational'. This necessarily loses some precision.
-instance From.From Rational Double where
-  from = fromRational
-
--- | Uses `fromRational` as long as there isn't a loss of precision.
-instance Fixed.HasResolution a => TryFrom.TryFrom Rational (Fixed.Fixed a) where
-  tryFrom = Utility.eitherTryFrom $ \s ->
-    let
-      t :: Fixed.Fixed a
-      t = fromRational s
-    in if toRational t == s then Right t else Left Exception.LossOfPrecision
-
--- Fixed
-
--- | Uses 'Fixed.MkFixed'. This means @from \@Integer \@Centi 2@ is @0.02@
--- rather than @2.00@.
-instance From.From Integer (Fixed.Fixed a) where
-  from = Fixed.MkFixed
-
--- | Uses 'Fixed.MkFixed'. This means @from \@Centi \@Integer 3.00@ is @300@
--- rather than @3@.
-instance From.From (Fixed.Fixed a) Integer where
-  from (Fixed.MkFixed t) = t
-
--- | Uses 'toRational'.
-instance Fixed.HasResolution a => From.From (Fixed.Fixed a) Rational where
-  from = toRational
-
--- Complex
-
--- | Uses '(Complex.:+)' with an imaginary part of 0.
-instance Num a => From.From a (Complex.Complex a) where
-  from = (Complex.:+ 0)
-
--- | Uses 'Complex.realPart' when the imaginary part is 0.
-instance (Eq a, Num a) => TryFrom.TryFrom (Complex.Complex a) a where
-  tryFrom = Utility.eitherTryFrom $ \s -> if Complex.imagPart s == 0
-    then Right $ Complex.realPart s
-    else Left Exception.LossOfPrecision
-
--- NonEmpty
-
--- | Uses 'NonEmpty.nonEmpty'.
-instance TryFrom.TryFrom [a] (NonEmpty.NonEmpty a) where
-  tryFrom = Utility.maybeTryFrom NonEmpty.nonEmpty
-
--- | Uses 'NonEmpty.toList'.
-instance From.From (NonEmpty.NonEmpty a) [a] where
-  from = NonEmpty.toList
-
--- Set
-
--- | Uses 'Set.fromList'.
-instance Ord a => From.From [a] (Set.Set a) where
-  from = Set.fromList
-
--- | Uses 'Set.toAscList'.
-instance From.From (Set.Set a) [a] where
-  from = Set.toAscList
-
--- IntSet
-
--- | Uses 'IntSet.fromList'.
-instance From.From [Int] IntSet.IntSet where
-  from = IntSet.fromList
-
--- | Uses 'IntSet.toAscList'.
-instance From.From IntSet.IntSet [Int] where
-  from = IntSet.toAscList
-
--- Map
-
--- | Uses 'Map.fromList'. If there are duplicate keys, later values will
--- overwrite earlier ones.
-instance Ord k => From.From [(k, v)] (Map.Map k v) where
-  from = Map.fromList
-
--- | Uses 'Map.toAscList'.
-instance From.From (Map.Map k v) [(k, v)] where
-  from = Map.toAscList
-
--- IntMap
-
--- | Uses 'IntMap.fromList'. If there are duplicate keys, later values will
--- overwrite earlier ones.
-instance From.From [(Int, v)] (IntMap.IntMap v) where
-  from = IntMap.fromList
-
--- | Uses 'IntMap.toAscList'.
-instance From.From (IntMap.IntMap v) [(Int, v)] where
-  from = IntMap.toAscList
-
--- Seq
-
--- | Uses 'Seq.fromList'.
-instance From.From [a] (Seq.Seq a) where
-  from = Seq.fromList
-
--- | Uses 'Foldable.toList'.
-instance From.From (Seq.Seq a) [a] where
-  from = Foldable.toList
-
--- ByteString
-
--- | Uses 'ByteString.pack'.
-instance From.From [Word.Word8] ByteString.ByteString where
-  from = ByteString.pack
-
--- | Uses 'ByteString.unpack'.
-instance From.From ByteString.ByteString [Word.Word8] where
-  from = ByteString.unpack
-
--- | Uses 'LazyByteString.fromStrict'.
-instance From.From ByteString.ByteString LazyByteString.ByteString where
-  from = LazyByteString.fromStrict
-
--- | Uses 'ShortByteString.toShort'.
-instance From.From ByteString.ByteString ShortByteString.ShortByteString where
-  from = ShortByteString.toShort
-
--- | Uses 'Text.decodeUtf8''.
-instance TryFrom.TryFrom ByteString.ByteString Text.Text where
-  tryFrom = Utility.eitherTryFrom Text.decodeUtf8'
-
--- | Converts via 'Text.Text'.
-instance TryFrom.TryFrom ByteString.ByteString LazyText.Text where
-  tryFrom =
-    Utility.eitherTryFrom
-      $ fmap (Utility.into @LazyText.Text)
-      . Utility.tryInto @Text.Text
-
--- | Converts via 'Text.Text'.
-instance TryFrom.TryFrom ByteString.ByteString String where
-  tryFrom =
-    Utility.eitherTryFrom
-      $ fmap (Utility.into @String)
-      . Utility.tryInto @Text.Text
-
--- LazyByteString
-
--- | Uses 'LazyByteString.pack'.
-instance From.From [Word.Word8] LazyByteString.ByteString where
-  from = LazyByteString.pack
-
--- | Uses 'LazyByteString.unpack'.
-instance From.From LazyByteString.ByteString [Word.Word8] where
-  from = LazyByteString.unpack
-
--- | Uses 'LazyByteString.toStrict'.
-instance From.From LazyByteString.ByteString ByteString.ByteString where
-  from = LazyByteString.toStrict
-
--- | Uses 'LazyText.decodeUtf8''.
-instance TryFrom.TryFrom LazyByteString.ByteString LazyText.Text where
-  tryFrom = Utility.eitherTryFrom LazyText.decodeUtf8'
-
--- | Converts via 'LazyText.Text'.
-instance TryFrom.TryFrom LazyByteString.ByteString Text.Text where
-  tryFrom =
-    Utility.eitherTryFrom
-      $ fmap (Utility.into @Text.Text)
-      . Utility.tryInto @LazyText.Text
-
--- | Converts via 'LazyText.Text'.
-instance TryFrom.TryFrom LazyByteString.ByteString String where
-  tryFrom =
-    Utility.eitherTryFrom
-      $ fmap (Utility.into @String)
-      . Utility.tryInto @LazyText.Text
-
--- ShortByteString
-
--- | Uses 'ShortByteString.pack'.
-instance From.From [Word.Word8] ShortByteString.ShortByteString where
-  from = ShortByteString.pack
-
--- | Uses 'ShortByteString.unpack'.
-instance From.From ShortByteString.ShortByteString [Word.Word8] where
-  from = ShortByteString.unpack
-
--- | Uses 'ShortByteString.fromShort'.
-instance From.From ShortByteString.ShortByteString ByteString.ByteString where
-  from = ShortByteString.fromShort
-
--- Text
-
--- | Uses 'LazyText.fromStrict'.
-instance From.From Text.Text LazyText.Text where
-  from = LazyText.fromStrict
-
--- | Uses 'Text.encodeUtf8'.
-instance From.From Text.Text ByteString.ByteString where
-  from = Text.encodeUtf8
-
--- | Converts via 'ByteString.ByteString'.
-instance From.From Text.Text LazyByteString.ByteString where
-  from = Utility.via @ByteString.ByteString
-
--- LazyText
-
--- | Uses 'LazyText.toStrict'.
-instance From.From LazyText.Text Text.Text where
-  from = LazyText.toStrict
-
--- | Uses 'LazyText.encodeUtf8'.
-instance From.From LazyText.Text LazyByteString.ByteString where
-  from = LazyText.encodeUtf8
-
--- | Converts via 'LazyByteString.ByteString'.
-instance From.From LazyText.Text ByteString.ByteString where
-  from = Utility.via @LazyByteString.ByteString
-
--- String
-
--- | Uses 'Text.pack'. Some 'Char' values cannot be represented in 'Text.Text'
--- and will be replaced with @'\\xFFFD'@.
-instance From.From String Text.Text where
-  from = Text.pack
-
--- | Uses 'Text.unpack'.
-instance From.From Text.Text String where
-  from = Text.unpack
-
--- | Uses 'LazyText.pack'. Some 'Char' values cannot be represented in
--- 'LazyText.Text' and will be replaced with @'\\xFFFD'@.
-instance From.From String LazyText.Text where
-  from = LazyText.pack
-
--- | Uses 'LazyText.unpack'.
-instance From.From LazyText.Text String where
-  from = LazyText.unpack
-
--- | Converts via 'Text.Text'.
-instance From.From String ByteString.ByteString where
-  from = Utility.via @Text.Text
-
--- | Converts via 'LazyText.Text'.
-instance From.From String LazyByteString.ByteString where
-  from = Utility.via @LazyText.Text
-
--- TryFromException
-
--- | Uses @coerce@.
-instance From.From
-  (TryFromException.TryFromException s u)
-  (TryFromException.TryFromException s t)
-
--- Day
-
--- | Uses 'Time.ModifiedJulianDay'.
-instance From.From Integer Time.Day where
-  from = Time.ModifiedJulianDay
-
--- | Uses 'Time.toModifiedJulianDay'.
-instance From.From Time.Day Integer where
-  from = Time.toModifiedJulianDay
-
--- DayOfWeek
-
--- | Uses 'Time.dayOfWeek'.
-instance From.From Time.Day Time.DayOfWeek where
-  from = Time.dayOfWeek
-
--- UniversalTime
-
--- | Uses 'Time.ModJulianDate'.
-instance From.From Rational Time.UniversalTime where
-  from = Time.ModJulianDate
-
--- | Uses 'Time.getModJulianDate'.
-instance From.From Time.UniversalTime Rational where
-  from = Time.getModJulianDate
-
--- DiffTime
-
--- | Uses 'realToFrac'.
-instance From.From Fixed.Pico Time.DiffTime where
-  from = realToFrac
-
--- | Uses 'realToFrac'.
-instance From.From Time.DiffTime Fixed.Pico where
-  from = realToFrac
-
--- NominalDiffTime
-
--- | Uses 'Time.secondsToNominalDiffTime'.
-instance From.From Fixed.Pico Time.NominalDiffTime where
-  from = Time.secondsToNominalDiffTime
-
--- | Uses 'Time.nominalDiffTimeToSeconds'.
-instance From.From Time.NominalDiffTime Fixed.Pico where
-  from = Time.nominalDiffTimeToSeconds
-
--- POSIXTime
-
--- | Uses 'Time.systemToPOSIXTime'.
-instance From.From Time.SystemTime Time.POSIXTime where
-  from = Time.systemToPOSIXTime
-
--- | Uses 'Time.utcTimeToPOSIXSeconds'.
-instance From.From Time.UTCTime Time.POSIXTime where
-  from = Time.utcTimeToPOSIXSeconds
-
--- | Uses 'Time.posixSecondsToUTCTime'.
-instance From.From Time.POSIXTime Time.UTCTime where
-  from = Time.posixSecondsToUTCTime
-
--- SystemTime
-
--- | Uses 'Time.utcToSystemTime'.
-instance From.From Time.UTCTime Time.SystemTime where
-  from = Time.utcToSystemTime
-
--- | Uses 'Time.systemToTAITime'.
-instance From.From Time.SystemTime Time.AbsoluteTime where
-  from = Time.systemToTAITime
-
--- | Uses 'Time.systemToUTCTime'.
-instance From.From Time.SystemTime Time.UTCTime where
-  from = Time.systemToUTCTime
-
--- TimeOfDay
-
--- | Uses 'Time.timeToTimeOfDay'.
-instance From.From Time.DiffTime Time.TimeOfDay where
-  from = Time.timeToTimeOfDay
-
--- | Uses 'Time.dayFractionToTimeOfDay'.
-instance From.From Rational Time.TimeOfDay where
-  from = Time.dayFractionToTimeOfDay
-
--- | Uses 'Time.timeOfDayToTime'.
-instance From.From Time.TimeOfDay Time.DiffTime where
-  from = Time.timeOfDayToTime
-
--- | Uses 'Time.timeOfDayToDayFraction'.
-instance From.From Time.TimeOfDay Rational where
-  from = Time.timeOfDayToDayFraction
-
--- CalendarDiffTime
-
--- | Uses 'Time.calendarTimeDays'.
-instance From.From Time.CalendarDiffDays Time.CalendarDiffTime where
-  from = Time.calendarTimeDays
-
--- | Uses 'Time.calendarTimeTime'.
-instance From.From Time.NominalDiffTime Time.CalendarDiffTime where
-  from = Time.calendarTimeTime
-
--- ZonedTime
-
--- | Uses 'Time.zonedTimeToUTC'.
-instance From.From Time.ZonedTime Time.UTCTime where
-  from = Time.zonedTimeToUTC
-
---
-
-realFloatToRational
-  :: RealFloat s => s -> Either Exception.ArithException Rational
-realFloatToRational s
-  | isNaN s = Left Exception.LossOfPrecision
-  | isInfinite s = if s > 0
-    then Left Exception.Overflow
-    else Left Exception.Underflow
-  | otherwise = Right $ overPositive
-    (uncurry makeRational . uncurry fromDigits . Numeric.floatToDigits 10)
-    s
-
-overPositive :: (Eq a, Num a, Num b) => (a -> b) -> a -> b
-overPositive f x = if signum x == -1 then -(f (-x)) else f x
-
-fromDigits :: [Int] -> Int -> (Integer, Integer)
-fromDigits ds e =
-  List.foldl' (\(a, n) d -> (a * 10 + toInteger d, n - 1)) (0, toInteger e) ds
-
-makeRational :: Integer -> Integer -> Rational
-makeRational d e = toRational d * 10 ^^ e
-
-fromNonNegativeIntegral
-  :: (Integral s, Num t) => s -> Either Exception.ArithException t
-fromNonNegativeIntegral x =
-  if x < 0 then Left Exception.Underflow else Right $ fromIntegral x
-
--- | The maximum integral value that can be unambiguously represented as a
--- 'Float'. Equal to 16,777,215.
-maxFloat :: Num a => a
-maxFloat = 16777215
-
--- | The maximum integral value that can be unambiguously represented as a
--- 'Double'. Equal to 9,007,199,254,740,991.
-maxDouble :: Num a => a
-maxDouble = 9007199254740991
diff --git a/src/lib/Witch/TryFrom.hs b/src/lib/Witch/TryFrom.hs
deleted file mode 100644
--- a/src/lib/Witch/TryFrom.hs
+++ /dev/null
@@ -1,26 +0,0 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module Witch.TryFrom where
-
-import qualified Witch.TryFromException as TryFromException
-
--- | This type class is for converting values from some @source@ type into
--- some other @target@ type. The constraint @'TryFrom' source target@ means
--- that you may be able to convert from a value of type @source@ into a value
--- of type @target@, but that conversion may fail at runtime.
---
--- This type class is for conversions that can sometimes fail. If your
--- conversion always succeeds, consider implementing @From@ instead.
-class TryFrom source target where
-  -- | This method implements the conversion of a value between types. At call
-  -- sites you may want to use @tryInto@ instead.
-  --
-  -- > -- Avoid this:
-  -- > tryFrom (x :: s)
-  -- >
-  -- > -- Prefer this:
-  -- > tryFrom @s
-  --
-  -- Consider using @maybeTryFrom@ or @eitherTryFrom@ to implement this
-  -- method.
-  tryFrom :: source -> Either (TryFromException.TryFromException source target) target
diff --git a/src/lib/Witch/TryFromException.hs b/src/lib/Witch/TryFromException.hs
deleted file mode 100644
--- a/src/lib/Witch/TryFromException.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Witch.TryFromException where
-
-import qualified Control.Exception as Exception
-import qualified Data.Proxy as Proxy
-import qualified Data.Typeable as Typeable
-
--- | This exception is thrown when a @TryFrom@ conversion fails. It has the
--- original @source@ value that caused the failure and it knows the @target@
--- type it was trying to convert into. It also has an optional
--- 'Exception.SomeException' for communicating what went wrong while
--- converting.
-data TryFromException source target = TryFromException
-  source
-  (Maybe Exception.SomeException)
-
-instance
-  ( Show source
-  , Typeable.Typeable source
-  , Typeable.Typeable target
-  ) => Show (TryFromException source target) where
-  showsPrec d (TryFromException x e) =
-    showParen (d > 10)
-      $ showString "TryFromException @"
-      . showsPrec 11 (Typeable.typeRep (Proxy.Proxy :: Proxy.Proxy source))
-      . showString " @"
-      . showsPrec 11 (Typeable.typeRep (Proxy.Proxy :: Proxy.Proxy target))
-      . showChar ' '
-      . showsPrec 11 x
-      . showChar ' '
-      . showsPrec 11 e
-
-instance
-  ( Show source
-  , Typeable.Typeable source
-  , Typeable.Typeable target
-  ) => Exception.Exception (TryFromException source target)
diff --git a/src/lib/Witch/Utility.hs b/src/lib/Witch/Utility.hs
deleted file mode 100644
--- a/src/lib/Witch/Utility.hs
+++ /dev/null
@@ -1,187 +0,0 @@
-{-# LANGUAGE AllowAmbiguousTypes #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Witch.Utility where
-
-import qualified Control.Exception as Exception
-import qualified Data.Typeable as Typeable
-import qualified GHC.Stack as Stack
-import qualified Witch.From as From
-import qualified Witch.TryFrom as TryFrom
-import qualified Witch.TryFromException as TryFromException
-
--- | This is the same as 'id'. This can be an ergonomic way to pin down a
--- polymorphic type in a function pipeline. For example:
---
--- > -- Avoid this:
--- > f . (\ x -> x :: Int) . g
--- >
--- > -- Prefer this:
--- > f . as @Int . g
-as :: forall source . source -> source
-as = id
-
--- | This is the same as 'From.from' except that the type variables are in the
--- opposite order.
---
--- > -- Avoid this:
--- > from x :: t
--- >
--- > -- Prefer this:
--- > into @t x
-into :: forall target source . From.From source target => source -> target
-into = From.from
-
--- | This function converts from some @source@ type into some @target@ type,
--- applies the given function, then converts back into the @source@ type. This
--- is useful when you have two types that are isomorphic but some function
--- that only works with one of them.
---
--- > -- Avoid this:
--- > from @t . f . into @t
--- >
--- > -- Prefer this:
--- > over @t f
-over
-  :: forall target source
-   . (From.From source target, From.From target source)
-  => (target -> target)
-  -> source
-  -> source
-over f = From.from . f . From.from
-
--- | This function first converts from some @source@ type into some @through@
--- type, and then converts that into some @target@ type. Usually this is used
--- when writing 'From.From' instances. Sometimes this can be used to work
--- around the lack of an instance that should probably exist.
---
--- > -- Avoid this:
--- > from @u . into @u
--- >
--- > -- Prefer this:
--- > via @u
-via
-  :: forall through source target
-   . (From.From source through, From.From through target)
-  => source
-  -> target
-via = From.from . (\x -> x :: through) . From.from
-
--- | This is the same as 'TryFrom.tryFrom' except that the type variables are
--- in the opposite order.
---
--- > -- Avoid this:
--- > tryFrom x :: Either (TryFromException s t) t
--- >
--- > -- Prefer this:
--- > tryInto @t x
-tryInto
-  :: forall target source
-   . TryFrom.TryFrom source target
-  => source
-  -> Either (TryFromException.TryFromException source target) target
-tryInto = TryFrom.tryFrom
-
--- | This is similar to 'via' except that it works with 'TryFrom.TryFrom'
--- instances instead. This function is especially convenient because juggling
--- the types in the 'TryFromException.TryFromException' can be tedious.
---
--- > -- Avoid this:
--- > case tryInto @u x of
--- >   Left (TryFromException _ e) -> Left $ TryFromException x e
--- >   Right y -> case tryFrom @u y of
--- >     Left (TryFromException _ e) -> Left $ TryFromException x e
--- >     Right z -> Right z
--- >
--- > -- Prefer this:
--- > tryVia @u
-tryVia
-  :: forall through source target
-   . (TryFrom.TryFrom source through, TryFrom.TryFrom through target)
-  => source
-  -> Either (TryFromException.TryFromException source target) target
-tryVia s = case TryFrom.tryFrom s of
-  Left (TryFromException.TryFromException _ e) ->
-    Left $ TryFromException.TryFromException s e
-  Right u -> case TryFrom.tryFrom (u :: through) of
-    Left (TryFromException.TryFromException _ e) ->
-      Left $ TryFromException.TryFromException s e
-    Right t -> Right t
-
--- | This function can be used to implement 'TryFrom.tryFrom' with a function
--- that returns 'Maybe'. For example:
---
--- > -- Avoid this:
--- > tryFrom s = case f s of
--- >   Nothing -> Left $ TryFromException s Nothing
--- >   Just t -> Right t
--- >
--- > -- Prefer this:
--- > tryFrom = maybeTryFrom f
-maybeTryFrom
-  :: (source -> Maybe target)
-  -> source
-  -> Either (TryFromException.TryFromException source target) target
-maybeTryFrom f s = case f s of
-  Nothing -> Left $ TryFromException.TryFromException s Nothing
-  Just t -> Right t
-
--- | This function can be used to implement 'TryFrom.tryFrom' with a function
--- that returns 'Either'. For example:
---
--- > -- Avoid this:
--- > tryFrom s = case f s of
--- >   Left e -> Left . TryFromException s . Just $ toException e
--- >   Right t -> Right t
--- >
--- > -- Prefer this:
--- > tryFrom = eitherTryFrom f
-eitherTryFrom
-  :: Exception.Exception exception
-  => (source -> Either exception target)
-  -> source
-  -> Either (TryFromException.TryFromException source target) target
-eitherTryFrom f s = case f s of
-  Left e ->
-    Left . TryFromException.TryFromException s . Just $ Exception.toException e
-  Right t -> Right t
-
--- | This function is like 'TryFrom.tryFrom' except that it will throw an
--- impure exception if the conversion fails.
---
--- > -- Avoid this:
--- > either throw id . tryFrom @s
--- >
--- > -- Prefer this:
--- > unsafeFrom @s
-unsafeFrom
-  :: forall source target
-   . ( Stack.HasCallStack
-     , TryFrom.TryFrom source target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> target
-unsafeFrom = either Exception.throw id . TryFrom.tryFrom
-
--- | This function is like 'tryInto' except that it will throw an impure
--- exception if the conversion fails.
---
--- > -- Avoid this:
--- > either throw id . tryInto @t
--- >
--- > -- Prefer this:
--- > unsafeInto @t
-unsafeInto
-  :: forall target source
-   . ( Stack.HasCallStack
-     , TryFrom.TryFrom source target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> target
-unsafeInto = unsafeFrom
diff --git a/src/test/Main.hs b/src/test/Main.hs
deleted file mode 100644
--- a/src/test/Main.hs
+++ /dev/null
@@ -1,1931 +0,0 @@
-{-# OPTIONS_GHC -Wno-error=overflowed-literals #-}
-
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE NegativeLiterals #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeApplications #-}
-
-import qualified Control.Exception as Exception
-import qualified Data.ByteString as ByteString
-import qualified Data.ByteString.Lazy as LazyByteString
-import qualified Data.ByteString.Short as ShortByteString
-import qualified Data.Complex as Complex
-import qualified Data.Either as Either
-import qualified Data.Fixed as Fixed
-import qualified Data.Int as Int
-import qualified Data.IntMap as IntMap
-import qualified Data.IntSet as IntSet
-import qualified Data.List.NonEmpty as NonEmpty
-import qualified Data.Map as Map
-import qualified Data.Ratio as Ratio
-import qualified Data.Sequence as Seq
-import qualified Data.Set as Set
-import qualified Data.Text as Text
-import qualified Data.Text.Lazy as LazyText
-import qualified Data.Time as Time
-import qualified Data.Time.Clock.POSIX as Time
-import qualified Data.Time.Clock.System as Time
-import qualified Data.Time.Clock.TAI as Time
-import qualified Data.Word as Word
-import qualified Numeric.Natural as Natural
-import Test.HUnit (Test(TestCase), assertBool, runTestTTAndExit, (~:), (~?=))
-import qualified Witch
-
-main :: IO ()
-main =
-  runTestTTAndExit
-    $ "Witch"
-    ~: [ "From" ~: ["from" ~: [Witch.from (1 :: Int.Int8) ~?= (1 :: Int.Int16)]]
-       , "TryFrom"
-         ~: [ "tryFrom"
-                ~: let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8
-                   in [f 1 ~?= Just 1, f 128 ~?= Nothing]
-            ]
-       , "Utility"
-         ~: [ "as" ~: [Witch.as @Int.Int8 1 ~?= 1]
-            , "from" ~: [Witch.from @Int.Int8 1 ~?= (1 :: Int.Int16)]
-            , "into" ~: [Witch.into @Int.Int16 (1 :: Int.Int8) ~?= 1]
-            , "over" ~: [Witch.over @Int.Int8 (+ 1) (Age 1) ~?= Age 2]
-            , "via"
-              ~: [Witch.via @Int.Int16 (1 :: Int.Int8) ~?= (1 :: Int.Int32)]
-            , "tryFrom"
-              ~: [hush (Witch.tryFrom @Int.Int16 1) ~?= Just (1 :: Int.Int8)]
-            , "tryInto"
-              ~: [hush (Witch.tryInto @Int.Int8 (1 :: Int.Int16)) ~?= Just 1]
-            , "tryVia"
-              ~: let f = Witch.tryVia @Int.Int16 @Int.Int32 @Int.Int8
-                 in
-                   [ hush (f 1) ~?= Just 1
-                   , hush (f 128) ~?= Nothing
-                   , hush (f 32768) ~?= Nothing
-                   ]
-            , "unsafeFrom"
-              ~: let f = Witch.unsafeFrom @Int.Int16 @Int.Int8
-                 in
-                   [ f 1 ~?= 1
-                   , TestCase $ do
-                     result <-
-                       Exception.try @Exception.SomeException
-                       . Exception.evaluate
-                       $ f 128
-                     assertBool (show result) $ Either.isLeft result
-                   ]
-            , "unsafeInto"
-              ~: [Witch.unsafeInto @Int.Int8 (1 :: Int.Int16) ~?= 1]
-            ]
-       , "Lift"
-         ~: [ "liftedFrom"
-              ~: [($$(Witch.liftedFrom (1 :: Int.Int16)) :: Int.Int8) ~?= 1]
-            , "liftedInto"
-              ~: [$$(Witch.liftedInto @Int.Int8 (1 :: Int.Int16)) ~?= 1]
-            ]
-       , "TryFromException"
-         ~: [ "show"
-                ~: [ show (Witch.TryFromException @Int @Int 0 Nothing)
-                     ~?= "TryFromException @Int @Int 0 Nothing"
-                   , show
-                       (Witch.TryFromException @(Seq.Seq Int) @(Seq.Seq Int)
-                         (Seq.fromList [])
-                         (Just (Exception.toException Exception.Overflow))
-                       )
-                     ~?= "TryFromException @(Seq Int) @(Seq Int) (fromList []) (Just arithmetic overflow)"
-                   ]
-            ]
-       , "Instances"
-         ~: [ "From a a" ~: let f = Witch.from @Int @Int in [f 0 ~?= 0]
-
-    -- Int8
-            , "From Int8 Int16"
-              ~: let f = Witch.from @Int.Int8 @Int.Int16
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-            , "From Int8 Int32"
-              ~: let f = Witch.from @Int.Int8 @Int.Int32
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-            , "From Int8 Int64"
-              ~: let f = Witch.from @Int.Int8 @Int.Int64
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-            , "From Int8 Int"
-              ~: let f = Witch.from @Int.Int8 @Int
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-            , "From Int8 Integer"
-              ~: let f = Witch.from @Int.Int8 @Integer
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-            , "TryFrom Int8 Word8"
-              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "TryFrom Int8 Word16"
-              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word16
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "TryFrom Int8 Word32"
-              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word32
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "TryFrom Int8 Word64"
-              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word.Word64
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "TryFrom Int8 Word"
-              ~: let f = hush . Witch.tryFrom @Int.Int8 @Word
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "TryFrom Int8 Natural"
-              ~: let f = hush . Witch.tryFrom @Int.Int8 @Natural.Natural
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "From Int8 Float"
-              ~: let f = Witch.from @Int.Int8 @Float
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-            , "From Int8 Double"
-              ~: let f = Witch.from @Int.Int8 @Double
-                 in [f 0 ~?= 0, f 127 ~?= 127, f (-128) ~?= (-128)]
-
-    -- Int16
-            , "TryFrom Int16 Int8"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   ]
-            , "From Int16 Int32"
-              ~: let f = Witch.from @Int.Int16 @Int.Int32
-                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
-            , "From Int16 Int64"
-              ~: let f = Witch.from @Int.Int16 @Int.Int64
-                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
-            , "From Int16 Int"
-              ~: let f = Witch.from @Int.Int16 @Int
-                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
-            , "From Int16 Integer"
-              ~: let f = Witch.from @Int.Int16 @Integer
-                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
-            , "TryFrom Int16 Word8"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int16 Word16"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word16
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f (-1) ~?= Nothing]
-            , "TryFrom Int16 Word32"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word32
-                 in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
-            , "TryFrom Int16 Word64"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word.Word64
-                 in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
-            , "TryFrom Int16 Word"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Word
-                 in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
-            , "TryFrom Int16 Natural"
-              ~: let f = hush . Witch.tryFrom @Int.Int16 @Natural.Natural
-                 in [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f (-1) ~?= Nothing]
-            , "From Int16 Float"
-              ~: let f = Witch.from @Int.Int16 @Float
-                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
-            , "From Int16 Double"
-              ~: let f = Witch.from @Int.Int16 @Double
-                 in [f 0 ~?= 0, f 32767 ~?= 32767, f (-32768) ~?= (-32768)]
-
-    -- Int32
-            , "TryFrom Int32 Int8"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Int16"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Int.Int16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 32767 ~?= Just 32767
-                   , f 32768 ~?= Nothing
-                   , f (-32768) ~?= Just (-32768)
-                   , f (-32769) ~?= Nothing
-                   ]
-            , "From Int32 Int64"
-              ~: let f = Witch.from @Int.Int32 @Int.Int64
-                 in
-                   [ f 0 ~?= 0
-                   , f 2147483647 ~?= 2147483647
-                   , f (-2147483648) ~?= (-2147483648)
-                   ]
-            , "TryFrom Int32 Int"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f (-2147483648) ~?= Just (-2147483648)
-                   ]
-            , "From Int32 Integer"
-              ~: let f = Witch.from @Int.Int32 @Integer
-                 in
-                   [ f 0 ~?= 0
-                   , f 2147483647 ~?= 2147483647
-                   , f (-2147483648) ~?= (-2147483648)
-                   ]
-            , "TryFrom Int32 Word8"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Word16"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 65535 ~?= Just 65535
-                   , f 65536 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Word32"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Word64"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Word"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Natural"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Natural.Natural
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int32 Float"
-              ~: let f = hush . Witch.tryFrom @Int.Int32 @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   ]
-            , "From Int32 Double"
-              ~: let f = Witch.from @Int.Int32 @Double
-                 in
-                   [ f 0 ~?= 0
-                   , f 2147483647 ~?= 2147483647
-                   , f (-2147483648) ~?= (-2147483648)
-                   ]
-
-    -- Int64
-            , "TryFrom Int64 Int8"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Int16"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int.Int16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 32767 ~?= Just 32767
-                   , f 32768 ~?= Nothing
-                   , f (-32768) ~?= Just (-32768)
-                   , f (-32769) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Int32"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   , f (-2147483648) ~?= Just (-2147483648)
-                   , f (-2147483649) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Int"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 9223372036854775807
-                         then f 9223372036854775807 ~?= Just 9223372036854775807
-                         else f (fromIntegral x) ~?= Just x
-                   , let x = minBound :: Int
-                     in
-                       if toInteger x <= (-9223372036854775808)
-                         then f (-9223372036854775808)
-                           ~?= Just (-9223372036854775808)
-                         else f (fromIntegral x) ~?= Just x
-                   ]
-            , "From Int64 Integer"
-              ~: let f = Witch.from @Int.Int64 @Integer
-                 in
-                   [ f 0 ~?= 0
-                   , f 9223372036854775807 ~?= 9223372036854775807
-                   , f (-9223372036854775808) ~?= (-9223372036854775808)
-                   ]
-            , "TryFrom Int64 Word8"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Word16"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 65535 ~?= Just 65535
-                   , f 65536 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Word32"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Word64"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9223372036854775807 ~?= Just 9223372036854775807
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Word"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 9223372036854775807
-                         then f 9223372036854775807 ~?= Just 9223372036854775807
-                         else f (fromIntegral x) ~?= Just x
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Natural"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Natural.Natural
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9223372036854775807 ~?= Just 9223372036854775807
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Float"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   ]
-            , "TryFrom Int64 Double"
-              ~: let f = hush . Witch.tryFrom @Int.Int64 @Double
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   , f (-9007199254740991) ~?= Just (-9007199254740991)
-                   , f (-9007199254740992) ~?= Nothing
-                   ]
-
-    -- Int
-            , "TryFrom Int Int8"
-              ~: let f = hush . Witch.tryFrom @Int @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   ]
-            , "TryFrom Int Int16"
-              ~: let f = hush . Witch.tryFrom @Int @Int.Int16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 32767 ~?= Just 32767
-                   , f 32768 ~?= Nothing
-                   , f (-32768) ~?= Just (-32768)
-                   , f (-32769) ~?= Nothing
-                   ]
-            , "TryFrom Int Int32"
-              ~: let f = hush . Witch.tryFrom @Int @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 2147483648
-                         then f 2147483648 ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   , f (-2147483648) ~?= Just (-2147483648)
-                   , let x = minBound :: Int
-                     in
-                       if toInteger x <= (-2147483649)
-                         then f (-2147483649) ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   ]
-            , "From Int Int64"
-              ~: let f = Witch.from @Int @Int.Int64
-                 in
-                   [ f 0 ~?= 0
-                   , f maxBound ~?= fromIntegral (maxBound :: Int)
-                   , f minBound ~?= fromIntegral (minBound :: Int)
-                   ]
-            , "From Int Integer"
-              ~: let f = Witch.from @Int @Integer
-                 in
-                   [ f 0 ~?= 0
-                   , f maxBound ~?= fromIntegral (maxBound :: Int)
-                   , f minBound ~?= fromIntegral (minBound :: Int)
-                   ]
-            , "TryFrom Int Word8"
-              ~: let f = hush . Witch.tryFrom @Int @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int Word16"
-              ~: let f = hush . Witch.tryFrom @Int @Word.Word16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 65535 ~?= Just 65535
-                   , f 65536 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int Word32"
-              ~: let f = hush . Witch.tryFrom @Int @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 4294967295
-                         then f 4294967295 ~?= Just 4294967295
-                         else f x ~?= Just (fromIntegral x)
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 4294967296
-                         then f 4294967296 ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int Word64"
-              ~: let f = hush . Witch.tryFrom @Int @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f maxBound ~?= Just (fromIntegral (maxBound :: Int))
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int Word"
-              ~: let f = hush . Witch.tryFrom @Int @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , f maxBound ~?= Just (fromIntegral (maxBound :: Int))
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int Natural"
-              ~: let f = hush . Witch.tryFrom @Int @Natural.Natural
-                 in
-                   [ f 0 ~?= Just 0
-                   , f maxBound ~?= Just (fromIntegral (maxBound :: Int))
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Int Float"
-              ~: let f = hush . Witch.tryFrom @Int @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   ]
-            , "TryFrom Int Double"
-              ~: let f = hush . Witch.tryFrom @Int @Double
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 9007199254740991
-                         then f 9007199254740991 ~?= Just 9007199254740991
-                         else f x ~?= Just (fromIntegral x)
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 9007199254740992
-                         then f 9007199254740992 ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   , let x = minBound :: Int
-                     in
-                       if toInteger x <= (-9007199254740991)
-                         then f (-9007199254740991) ~?= Just (-9007199254740991)
-                         else f x ~?= Just (fromIntegral x)
-                   , let x = minBound :: Int
-                     in
-                       if toInteger x <= (-9007199254740992)
-                         then f (-9007199254740992) ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   ]
-
-    -- Integer
-            , "TryFrom Integer Int8"
-              ~: let f = hush . Witch.tryFrom @Integer @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   ]
-            , "TryFrom Integer Int16"
-              ~: let f = hush . Witch.tryFrom @Integer @Int.Int16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 32767 ~?= Just 32767
-                   , f 32768 ~?= Nothing
-                   , f (-32768) ~?= Just (-32768)
-                   , f (-32769) ~?= Nothing
-                   ]
-            , "TryFrom Integer Int32"
-              ~: let f = hush . Witch.tryFrom @Integer @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   , f (-2147483648) ~?= Just (-2147483648)
-                   , f (-2147483649) ~?= Nothing
-                   ]
-            , "TryFrom Integer Int64"
-              ~: let f = hush . Witch.tryFrom @Integer @Int.Int64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9223372036854775807 ~?= Just 9223372036854775807
-                   , f 9223372036854775808 ~?= Nothing
-                   , f (-9223372036854775808) ~?= Just (-9223372036854775808)
-                   , f (-9223372036854775809) ~?= Nothing
-                   ]
-            , "TryFrom Integer Int"
-              ~: let f = hush . Witch.tryFrom @Integer @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int in f (fromIntegral x) ~?= Just x
-                   , let x = toInteger (maxBound :: Int) + 1 in f x ~?= Nothing
-                   , let x = minBound :: Int in f (fromIntegral x) ~?= Just x
-                   , let x = toInteger (minBound :: Int) - 1 in f x ~?= Nothing
-                   ]
-            , "TryFrom Integer Word8"
-              ~: let f = hush . Witch.tryFrom @Integer @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Integer Word16"
-              ~: let f = hush . Witch.tryFrom @Integer @Word.Word16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 65535 ~?= Just 65535
-                   , f 65536 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Integer Word32"
-              ~: let f = hush . Witch.tryFrom @Integer @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 4294967295 ~?= Just 4294967295
-                   , f 4294967296 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Integer Word64"
-              ~: let f = hush . Witch.tryFrom @Integer @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 18446744073709551615 ~?= Just 18446744073709551615
-                   , f 18446744073709551616 ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Integer Word"
-              ~: let f = hush . Witch.tryFrom @Integer @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word in f (fromIntegral x) ~?= Just x
-                   , let x = toInteger (maxBound :: Word) + 1
-                     in f x ~?= Nothing
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Integer Natural"
-              ~: let f = hush . Witch.tryFrom @Integer @Natural.Natural
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 18446744073709551616 ~?= Just 18446744073709551616
-                   , f (-1) ~?= Nothing
-                   ]
-            , "TryFrom Integer Float"
-              ~: let f = hush . Witch.tryFrom @Integer @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   ]
-            , "TryFrom Integer Double"
-              ~: let f = hush . Witch.tryFrom @Integer @Double
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   , f (-9007199254740991) ~?= Just (-9007199254740991)
-                   , f (-9007199254740992) ~?= Nothing
-                   ]
-
-    -- Word8
-            , "From Word8 Word16"
-              ~: let f = Witch.from @Word.Word8 @Word.Word16
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Word32"
-              ~: let f = Witch.from @Word.Word8 @Word.Word32
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Word64"
-              ~: let f = Witch.from @Word.Word8 @Word.Word64
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Word"
-              ~: let f = Witch.from @Word.Word8 @Word
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Natural"
-              ~: let f = Witch.from @Word.Word8 @Natural.Natural
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "TryFrom Word8 Int8"
-              ~: let f = hush . Witch.tryFrom @Word.Word8 @Int.Int8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
-            , "From Word8 Int16"
-              ~: let f = Witch.from @Word.Word8 @Int.Int16
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Int32"
-              ~: let f = Witch.from @Word.Word8 @Int.Int32
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Int64"
-              ~: let f = Witch.from @Word.Word8 @Int.Int64
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Int"
-              ~: let f = Witch.from @Word.Word8 @Int
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Integer"
-              ~: let f = Witch.from @Word.Word8 @Integer
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Float"
-              ~: let f = Witch.from @Word.Word8 @Float
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-            , "From Word8 Double"
-              ~: let f = Witch.from @Word.Word8 @Double
-                 in [f 0 ~?= 0, f 255 ~?= 255]
-
-    -- Word16
-            , "TryFrom Word16 Word8"
-              ~: let f = hush . Witch.tryFrom @Word.Word16 @Word.Word8
-                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
-            , "From Word16 Word32"
-              ~: let f = Witch.from @Word.Word16 @Word.Word32
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Word64"
-              ~: let f = Witch.from @Word.Word16 @Word.Word64
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Word"
-              ~: let f = Witch.from @Word.Word16 @Word
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Natural"
-              ~: let f = Witch.from @Word.Word16 @Natural.Natural
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "TryFrom Word16 Int8"
-              ~: let f = hush . Witch.tryFrom @Word.Word16 @Int.Int8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
-            , "TryFrom Word16 Int16"
-              ~: let f = hush . Witch.tryFrom @Word.Word16 @Int.Int16
-                 in
-                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing]
-            , "From Word16 Int32"
-              ~: let f = Witch.from @Word.Word16 @Int.Int32
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Int64"
-              ~: let f = Witch.from @Word.Word16 @Int.Int64
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Int"
-              ~: let f = Witch.from @Word.Word16 @Int
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Integer"
-              ~: let f = Witch.from @Word.Word16 @Integer
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Float"
-              ~: let f = Witch.from @Word.Word16 @Float
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-            , "From Word16 Double"
-              ~: let f = Witch.from @Word.Word16 @Double
-                 in [f 0 ~?= 0, f 65535 ~?= 65535]
-
-    -- Word32
-            , "TryFrom Word32 Word8"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Word.Word8
-                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
-            , "TryFrom Word32 Word16"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Word.Word16
-                 in
-                   [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing]
-            , "From Word32 Word64"
-              ~: let f = Witch.from @Word.Word32 @Word.Word64
-                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
-            , "TryFrom Word32 Word"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Word
-                 in [f 0 ~?= Just 0, f 4294967295 ~?= Just 4294967295]
-            , "From Word32 Natural"
-              ~: let f = Witch.from @Word.Word32 @Natural.Natural
-                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
-            , "TryFrom Word32 Int8"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
-            , "TryFrom Word32 Int16"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int16
-                 in
-                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing]
-            , "TryFrom Word32 Int32"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   ]
-            , "From Word32 Int64"
-              ~: let f = Witch.from @Word.Word32 @Int.Int64
-                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
-            , "TryFrom Word32 Int"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 4294967295
-                         then f 4294967295 ~?= Just 4294967295
-                         else f (fromIntegral x) ~?= Just x
-                   ]
-            , "From Word32 Integer"
-              ~: let f = Witch.from @Word.Word32 @Integer
-                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
-            , "TryFrom Word32 Float"
-              ~: let f = hush . Witch.tryFrom @Word.Word32 @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   ]
-            , "From Word32 Double"
-              ~: let f = Witch.from @Word.Word32 @Double
-                 in [f 0 ~?= 0, f 4294967295 ~?= 4294967295]
-
-    -- Word64
-            , "TryFrom Word64 Word8"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word8
-                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
-            , "TryFrom Word64 Word16"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word16
-                 in
-                   [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing]
-            , "TryFrom Word64 Word32"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 4294967295 ~?= Just 4294967295
-                   , f 4294967296 ~?= Nothing
-                   ]
-            , "TryFrom Word64 Word"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 18446744073709551615
-                         then f 18446744073709551615
-                           ~?= Just 18446744073709551615
-                         else f (fromIntegral x) ~?= Just x
-                   ]
-            , "From Word64 Natural"
-              ~: let f = Witch.from @Word.Word64 @Natural.Natural
-                 in [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615]
-            , "TryFrom Word64 Int8"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
-            , "TryFrom Word64 Int16"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int16
-                 in
-                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing]
-            , "TryFrom Word64 Int32"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   ]
-            , "TryFrom Word64 Int64"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int.Int64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9223372036854775807 ~?= Just 9223372036854775807
-                   , f 9223372036854775808 ~?= Nothing
-                   ]
-            , "TryFrom Word64 Int"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       hush (Witch.tryFrom @Word.Word64 @Int (fromIntegral x))
-                         ~?= Just x
-                   , let x = fromIntegral (maxBound :: Int) + 1 :: Word.Word64
-                     in hush (Witch.tryFrom @Word.Word64 @Int x) ~?= Nothing
-                   ]
-            , "From Word64 Integer"
-              ~: let f = Witch.from @Word.Word64 @Integer
-                 in [f 0 ~?= 0, f 18446744073709551615 ~?= 18446744073709551615]
-            , "TryFrom Word64 Float"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   ]
-            , "TryFrom Word64 Double"
-              ~: let f = hush . Witch.tryFrom @Word.Word64 @Double
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   ]
-
-    -- Word
-            , "TryFrom Word Word8"
-              ~: let f = hush . Witch.tryFrom @Word @Word.Word8
-                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
-            , "TryFrom Word Word16"
-              ~: let f = hush . Witch.tryFrom @Word @Word.Word16
-                 in
-                   [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing]
-            , "TryFrom Word Word32"
-              ~: let f = hush . Witch.tryFrom @Word @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 4294967295 ~?= Just 4294967295
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 4294967296
-                         then f 4294967296 ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   ]
-            , "From Word Word64"
-              ~: let f = Witch.from @Word @Word.Word64
-                 in [f 0 ~?= 0, f maxBound ~?= fromIntegral (maxBound :: Word)]
-            , "From Word Natural"
-              ~: let f = Witch.from @Word @Natural.Natural
-                 in [f 0 ~?= 0, f maxBound ~?= fromIntegral (maxBound :: Word)]
-            , "TryFrom Word Int8"
-              ~: let f = hush . Witch.tryFrom @Word @Int.Int8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
-            , "TryFrom Word Int16"
-              ~: let f = hush . Witch.tryFrom @Word @Int.Int16
-                 in
-                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing]
-            , "TryFrom Word Int32"
-              ~: let f = hush . Witch.tryFrom @Word @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   ]
-            , "TryFrom Word Int64"
-              ~: let f = hush . Witch.tryFrom @Word @Int.Int64
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 9223372036854775807
-                         then f 9223372036854775807 ~?= Just 9223372036854775807
-                         else f x ~?= Just (fromIntegral x)
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 9223372036854775808
-                         then f 9223372036854775808 ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   ]
-            , "TryFrom Word Int"
-              ~: let f = hush . Witch.tryFrom @Word @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       hush (Witch.tryFrom @Word @Int (fromIntegral x))
-                         ~?= Just x
-                   , let x = fromIntegral (maxBound :: Int) + 1 :: Word
-                     in hush (Witch.tryFrom @Word @Int x) ~?= Nothing
-                   ]
-            , "From Word Integer"
-              ~: let f = Witch.from @Word @Integer
-                 in [f 0 ~?= 0, f maxBound ~?= fromIntegral (maxBound :: Word)]
-            , "TryFrom Word Float"
-              ~: let f = hush . Witch.tryFrom @Word @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   ]
-            , "TryFrom Word Double"
-              ~: let f = hush . Witch.tryFrom @Word @Double
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 9007199254740991
-                         then f 9007199254740991 ~?= Just 9007199254740991
-                         else f x ~?= Just (fromIntegral x)
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 9007199254740992
-                         then f 9007199254740992 ~?= Nothing
-                         else f x ~?= Just (fromIntegral x)
-                   ]
-
-    -- Natural
-            , "TryFrom Natural Word8"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word8
-                 in [f 0 ~?= Just 0, f 255 ~?= Just 255, f 256 ~?= Nothing]
-            , "TryFrom Natural Word16"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word16
-                 in
-                   [f 0 ~?= Just 0, f 65535 ~?= Just 65535, f 65536 ~?= Nothing]
-            , "TryFrom Natural Word32"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 4294967295 ~?= Just 4294967295
-                   , f 4294967296 ~?= Nothing
-                   ]
-            , "TryFrom Natural Word64"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 18446744073709551615 ~?= Just 18446744073709551615
-                   , f 18446744073709551616 ~?= Nothing
-                   ]
-            , "TryFrom Natural Word"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word
-                     in
-                       hush
-                           (Witch.tryFrom @Natural.Natural @Word
-                             (fromIntegral x)
-                           )
-                         ~?= Just x
-                   , let
-                       x =
-                         fromIntegral (maxBound :: Word) + 1 :: Natural.Natural
-                     in
-                       hush (Witch.tryFrom @Natural.Natural @Word x) ~?= Nothing
-                   ]
-            , "TryFrom Natural Int8"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int8
-                 in [f 0 ~?= Just 0, f 127 ~?= Just 127, f 128 ~?= Nothing]
-            , "TryFrom Natural Int16"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int16
-                 in
-                   [f 0 ~?= Just 0, f 32767 ~?= Just 32767, f 32768 ~?= Nothing]
-            , "TryFrom Natural Int32"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   ]
-            , "TryFrom Natural Int64"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int.Int64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9223372036854775807 ~?= Just 9223372036854775807
-                   , f 9223372036854775808 ~?= Nothing
-                   ]
-            , "TryFrom Natural Int"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       hush
-                           (Witch.tryFrom @Natural.Natural @Int (fromIntegral x)
-                           )
-                         ~?= Just x
-                   , let
-                       x =
-                         fromIntegral (maxBound :: Int) + 1 :: Natural.Natural
-                     in hush (Witch.tryFrom @Natural.Natural @Int x) ~?= Nothing
-                   ]
-            , "From Natural Integer"
-              ~: let f = Witch.from @Natural.Natural @Integer
-                 in [f 0 ~?= 0, f 9223372036854775808 ~?= 9223372036854775808]
-            , "TryFrom Natural Float"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Float
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   ]
-            , "TryFrom Natural Double"
-              ~: let f = hush . Witch.tryFrom @Natural.Natural @Double
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   ]
-
-    -- Float
-            , "TryFrom Float Int8"
-              ~: let f = hush . Witch.tryFrom @Float @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Int16"
-              ~: let f = hush . Witch.tryFrom @Float @Int.Int16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 32767 ~?= Just 32767
-                   , f 32768 ~?= Nothing
-                   , f (-32768) ~?= Just (-32768)
-                   , f (-32769) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Int32"
-              ~: let f = hush . Witch.tryFrom @Float @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Int64"
-              ~: let f = hush . Witch.tryFrom @Float @Int.Int64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Int"
-              ~: let f = hush . Witch.tryFrom @Float @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Integer"
-              ~: let f = hush . Witch.tryFrom @Float @Integer
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f (-16777216) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Word8"
-              ~: let f = hush . Witch.tryFrom @Float @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Word16"
-              ~: let f = hush . Witch.tryFrom @Float @Word.Word16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 65535 ~?= Just 65535
-                   , f 65536 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Word32"
-              ~: let f = hush . Witch.tryFrom @Float @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Word64"
-              ~: let f = hush . Witch.tryFrom @Float @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Word"
-              ~: let f = hush . Witch.tryFrom @Float @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Natural"
-              ~: let f = hush . Witch.tryFrom @Float @Natural.Natural
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 16777215 ~?= Just 16777215
-                   , f 16777216 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Float Rational"
-              ~: let f = hush . Witch.tryFrom @Float @Rational
-                 in
-                   [ f 0 ~?= Just 0
-                   , f (-0) ~?= Just 0
-                   , f 0.5 ~?= Just 0.5
-                   , f (-0.5) ~?= Just (-0.5)
-                   , f 16777215 ~?= Just 16777215
-                   , f (-16777215) ~?= Just (-16777215)
-                   , f 16777216 ~?= Just 16777216
-                   , f (-16777216) ~?= Just (-16777216)
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   , f 0.1 ~?= Just 0.1
-                   , f (-0.1) ~?= Just (-0.1)
-                   ]
-            , "From Float Double"
-              ~: let f = Witch.from @Float @Double
-                 in
-                   [ f 0 ~?= 0
-                   , f 0.5 ~?= 0.5
-                   , f (-0.5) ~?= (-0.5)
-                   , TestCase
-                     $ let x = f (0 / 0) in assertBool (show x) $ isNaN x
-                   , f (1 / 0) ~?= (1 / 0)
-                   , f (-1 / 0) ~?= (-1 / 0)
-                   ]
-
-    -- Double
-            , "TryFrom Double Int8"
-              ~: let f = hush . Witch.tryFrom @Double @Int.Int8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 127 ~?= Just 127
-                   , f 128 ~?= Nothing
-                   , f (-128) ~?= Just (-128)
-                   , f (-129) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Int16"
-              ~: let f = hush . Witch.tryFrom @Double @Int.Int16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 32767 ~?= Just 32767
-                   , f 32768 ~?= Nothing
-                   , f (-32768) ~?= Just (-32768)
-                   , f (-32769) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Int32"
-              ~: let f = hush . Witch.tryFrom @Double @Int.Int32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 2147483647 ~?= Just 2147483647
-                   , f 2147483648 ~?= Nothing
-                   , f (-2147483648) ~?= Just (-2147483648)
-                   , f (-2147483649) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Int64"
-              ~: let f = hush . Witch.tryFrom @Double @Int.Int64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   , f (-9007199254740991) ~?= Just (-9007199254740991)
-                   , f (-9007199254740992) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Int"
-              ~: let f = hush . Witch.tryFrom @Double @Int
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Int
-                     in
-                       if toInteger x >= 9007199254740991
-                         then f 9007199254740991 ~?= Just 9007199254740991
-                         else f (fromIntegral x) ~?= Just x
-                   , f 9007199254740992 ~?= Nothing
-                   , let x = minBound :: Int
-                     in
-                       if toInteger x <= (-9007199254740991)
-                         then f (-9007199254740991) ~?= Just (-9007199254740991)
-                         else f (fromIntegral x) ~?= Just x
-                   , f (-9007199254740992) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Integer"
-              ~: let f = hush . Witch.tryFrom @Double @Integer
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   , f (-9007199254740991) ~?= Just (-9007199254740991)
-                   , f (-9007199254740992) ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Word8"
-              ~: let f = hush . Witch.tryFrom @Double @Word.Word8
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 255 ~?= Just 255
-                   , f 256 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Word16"
-              ~: let f = hush . Witch.tryFrom @Double @Word.Word16
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 65535 ~?= Just 65535
-                   , f 65536 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Word32"
-              ~: let f = hush . Witch.tryFrom @Double @Word.Word32
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 4294967295 ~?= Just 4294967295
-                   , f 4294967296 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Word64"
-              ~: let f = hush . Witch.tryFrom @Double @Word.Word64
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Word"
-              ~: let f = hush . Witch.tryFrom @Double @Word
-                 in
-                   [ f 0 ~?= Just 0
-                   , let x = maxBound :: Word
-                     in
-                       if toInteger x >= 9007199254740991
-                         then f 9007199254740991 ~?= Just 9007199254740991
-                         else f (fromIntegral x) ~?= Just x
-                   , f 9007199254740992 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Natural"
-              ~: let f = hush . Witch.tryFrom @Double @Natural.Natural
-                 in
-                   [ f 0 ~?= Just 0
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f 9007199254740992 ~?= Nothing
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   ]
-            , "TryFrom Double Rational"
-              ~: let f = hush . Witch.tryFrom @Double @Rational
-                 in
-                   [ f 0 ~?= Just 0
-                   , f (-0) ~?= Just 0
-                   , f 0.5 ~?= Just 0.5
-                   , f (-0.5) ~?= Just (-0.5)
-                   , f 9007199254740991 ~?= Just 9007199254740991
-                   , f (-9007199254740991) ~?= Just (-9007199254740991)
-                   , f 9007199254740992 ~?= Just 9007199254740992
-                   , f (-9007199254740992) ~?= Just (-9007199254740992)
-                   , f (0 / 0) ~?= Nothing
-                   , f (1 / 0) ~?= Nothing
-                   , f (-1 / 0) ~?= Nothing
-                   , f 0.1 ~?= Just 0.1
-                   , f (-0.1) ~?= Just (-0.1)
-                   ]
-            , "From Double Float"
-              ~: let f = Witch.from @Double @Float
-                 in
-                   [ f 0 ~?= 0
-                   , f 0.5 ~?= 0.5
-                   , f (-0.5) ~?= (-0.5)
-                   , TestCase
-                     $ let x = f (0 / 0) in assertBool (show x) $ isNaN x
-                   , f (1 / 0) ~?= (1 / 0)
-                   , f (-1 / 0) ~?= (-1 / 0)
-                   ]
-
-    -- Ratio
-            , "From a (Ratio a)"
-              ~: let f = Witch.from @Int @(Ratio.Ratio Int)
-                 in [Witch.from @Integer @Rational 0 ~?= 0, f 0 ~?= 0]
-            , "TryFrom (Ratio a) a"
-              ~: let f = hush . Witch.tryFrom @(Ratio.Ratio Int) @Int
-                 in
-                   [ hush (Witch.tryFrom @Rational @Integer 0) ~?= Just 0
-                   , hush (Witch.tryFrom @Rational @Integer 0.5) ~?= Nothing
-                   , f 0 ~?= Just 0
-                   , f 0.5 ~?= Nothing
-                   ]
-            , "From Rational Float"
-              ~: let f = Witch.from @Rational @Float
-                 in
-                   [ f 0 ~?= 0
-                   , f 0.5 ~?= 0.5
-                   , f (-0.5) ~?= (-0.5)
-                   , f 0.1 ~?= 0.1
-                   , f (-0.1) ~?= (-0.1)
-                   ]
-            , "From Rational Double"
-              ~: let f = Witch.from @Rational @Double
-                 in
-                   [ f 0 ~?= 0
-                   , f 0.5 ~?= 0.5
-                   , f (-0.5) ~?= (-0.5)
-                   , f 0.1 ~?= 0.1
-                   , f (-0.1) ~?= (-0.1)
-                   ]
-            , "TryFrom Rational (Fixed a)"
-              ~: let f = hush . Witch.tryFrom @Rational @Fixed.Deci
-                 in
-                   [ hush (Witch.tryFrom @Rational @Fixed.Uni 1) ~?= Just 1
-                   , hush (Witch.tryFrom @Rational @Fixed.Uni 1.2) ~?= Nothing
-                   , f 0.1 ~?= Just 0.1
-                   , f 1.2 ~?= Just 1.2
-                   , f 12.3 ~?= Just 12.3
-                   , f 0.12 ~?= Nothing
-                   ]
-
-    -- Fixed
-            , "From Integer (Fixed a)"
-              ~: let f = Witch.from @Integer @Fixed.Deci
-                 in
-                   [ Witch.from @Integer @Fixed.Uni 1 ~?= 1
-                   , f 1 ~?= 0.1
-                   , f 10 ~?= 1
-                   , f 120 ~?= 12
-                   ]
-            , "From (Fixed a) Integer"
-              ~: let f = Witch.from @Fixed.Deci @Integer
-                 in
-                   [ Witch.from @Fixed.Uni @Integer 1 ~?= 1
-                   , f 0.1 ~?= 1
-                   , f 1 ~?= 10
-                   , f 12 ~?= 120
-                   ]
-            , "From (Fixed a) Rational"
-              ~: let f = Witch.from @Fixed.Deci @Rational
-                 in
-                   [ Witch.from @Fixed.Uni @Rational 1 ~?= 1
-                   , f 0.1 ~?= 0.1
-                   , f 1 ~?= 1
-                   , f 12 ~?= 12
-                   ]
-
-    -- Complex
-            , "From a (Complex a)"
-              ~: let f = Witch.from @Float @(Complex.Complex Float)
-                 in
-                   [ Witch.from @Double @(Complex.Complex Double) 1 ~?= 1
-                   , f 1 ~?= 1
-                   ]
-            , "TryFrom (Complex a) a"
-              ~: let f = hush . Witch.tryFrom @(Complex.Complex Float) @Float
-                 in
-                   [ hush (Witch.tryFrom @(Complex.Complex Double) @Double 1)
-                     ~?= Just 1
-                   , hush
-                       (Witch.tryFrom @(Complex.Complex Double) @Double
-                         (0 Complex.:+ 1)
-                       )
-                     ~?= Nothing
-                   , f 1 ~?= Just 1
-                   , f (0 Complex.:+ 1) ~?= Nothing
-                   ]
-
-    -- NonEmpty
-            , "TryFrom [a] (NonEmpty a)"
-              ~: let f = hush . Witch.tryFrom @[Int] @(NonEmpty.NonEmpty Int)
-                 in
-                   [ f [] ~?= Nothing
-                   , f [1] ~?= Just (1 NonEmpty.:| [])
-                   , f [1, 2] ~?= Just (1 NonEmpty.:| [2])
-                   ]
-            , "From (NonEmpty a) [a]"
-              ~: let f = Witch.from @(NonEmpty.NonEmpty Int) @[Int]
-                 in
-                   [ f (1 NonEmpty.:| []) ~?= [1]
-                   , f (1 NonEmpty.:| [2]) ~?= [1, 2]
-                   ]
-
-    -- Set
-            , "From [a] (Set a)"
-              ~: let f = Witch.from @[Char] @(Set.Set Char)
-                 in
-                   [ f [] ~?= Set.fromList []
-                   , f ['a'] ~?= Set.fromList ['a']
-                   , f ['a', 'b'] ~?= Set.fromList ['a', 'b']
-                   , f ['a', 'a'] ~?= Set.fromList ['a']
-                   ]
-            , "From (Set a) [a]"
-              ~: let f = Witch.from @(Set.Set Char) @[Char]
-                 in
-                   [ f (Set.fromList []) ~?= []
-                   , f (Set.fromList ['a']) ~?= ['a']
-                   , f (Set.fromList ['a', 'b']) ~?= ['a', 'b']
-                   ]
-
-    -- IntSet
-            , "From [Int] IntSet"
-              ~: let f = Witch.from @[Int] @IntSet.IntSet
-                 in
-                   [ f [] ~?= IntSet.fromList []
-                   , f [1] ~?= IntSet.fromList [1]
-                   , f [1, 2] ~?= IntSet.fromList [1, 2]
-                   ]
-            , "From IntSet [Int]"
-              ~: let f = Witch.from @IntSet.IntSet @[Int]
-                 in
-                   [ f (IntSet.fromList []) ~?= []
-                   , f (IntSet.fromList [1]) ~?= [1]
-                   , f (IntSet.fromList [1, 2]) ~?= [1, 2]
-                   ]
-
-    -- Map
-            , "From [(k, v)] (Map k v)"
-              ~: let f = Witch.from @[(Char, Int)] @(Map.Map Char Int)
-                 in
-                   [ f [] ~?= Map.empty
-                   , f [('a', 1)] ~?= Map.fromList [('a', 1)]
-                   , f [('a', 1), ('b', 2)]
-                     ~?= Map.fromList [('a', 1), ('b', 2)]
-                   , f [('a', 1), ('a', 2)] ~?= Map.fromList [('a', 2)]
-                   ]
-            , "From (Map k v) [(k, v)]"
-              ~: let f = Witch.from @(Map.Map Char Int) @[(Char, Int)]
-                 in
-                   [ f Map.empty ~?= []
-                   , f (Map.fromList [('a', 1)]) ~?= [('a', 1)]
-                   , f (Map.fromList [('a', 1), ('b', 2)])
-                     ~?= [('a', 1), ('b', 2)]
-                   ]
-
-    -- IntMap
-            , "From [(Int, v)] (IntMap v)"
-              ~: let f = Witch.from @[(Int, Char)] @(IntMap.IntMap Char)
-                 in
-                   [ f [] ~?= IntMap.fromList []
-                   , f [(1, 'a')] ~?= IntMap.fromList [(1, 'a')]
-                   , f [(1, 'a'), (2, 'b')]
-                     ~?= IntMap.fromList [(1, 'a'), (2, 'b')]
-                   , f [(1, 'a'), (1, 'b')] ~?= IntMap.fromList [(1, 'b')]
-                   ]
-            , "From (IntMap v) [(Int, v)]"
-              ~: let f = Witch.from @(IntMap.IntMap Char) @[(Int, Char)]
-                 in
-                   [ f (IntMap.fromList []) ~?= []
-                   , f (IntMap.fromList [(1, 'a')]) ~?= [(1, 'a')]
-                   , f (IntMap.fromList [(1, 'a'), (2, 'b')])
-                     ~?= [(1, 'a'), (2, 'b')]
-                   ]
-
-    -- Seq
-            , "From [a] (Seq a)"
-              ~: let f = Witch.from @[Int] @(Seq.Seq Int)
-                 in
-                   [ f [] ~?= Seq.fromList []
-                   , f [1] ~?= Seq.fromList [1]
-                   , f [1, 2] ~?= Seq.fromList [1, 2]
-                   ]
-            , "From (Seq a) [a]"
-              ~: let f = Witch.from @(Seq.Seq Int) @[Int]
-                 in
-                   [ f (Seq.fromList []) ~?= []
-                   , f (Seq.fromList [1]) ~?= [1]
-                   , f (Seq.fromList [1, 2]) ~?= [1, 2]
-                   ]
-
-    -- ByteString
-            , "From [Word8] ByteString"
-              ~: let f = Witch.from @[Word.Word8] @ByteString.ByteString
-                 in
-                   [ f [] ~?= ByteString.pack []
-                   , f [0x00] ~?= ByteString.pack [0x00]
-                   , f [0x0f, 0xf0] ~?= ByteString.pack [0x0f, 0xf0]
-                   ]
-            , "From ByteString [Word8]"
-              ~: let f = Witch.from @ByteString.ByteString @[Word.Word8]
-                 in
-                   [ f (ByteString.pack []) ~?= []
-                   , f (ByteString.pack [0x00]) ~?= [0x00]
-                   , f (ByteString.pack [0x0f, 0xf0]) ~?= [0x0f, 0xf0]
-                   ]
-            , "From ByteString LazyByteString"
-              ~: let
-                   f =
-                     Witch.from @ByteString.ByteString
-                       @LazyByteString.ByteString
-                 in
-                   [ f (ByteString.pack []) ~?= LazyByteString.pack []
-                   , f (ByteString.pack [0x00]) ~?= LazyByteString.pack [0x00]
-                   , f (ByteString.pack [0x0f, 0xf0])
-                     ~?= LazyByteString.pack [0x0f, 0xf0]
-                   ]
-            , "From ByteString ShortByteString"
-              ~: let
-                   f =
-                     Witch.from @ByteString.ByteString
-                       @ShortByteString.ShortByteString
-                 in
-                   [ f (ByteString.pack []) ~?= ShortByteString.pack []
-                   , f (ByteString.pack [0x00]) ~?= ShortByteString.pack [0x00]
-                   , f (ByteString.pack [0x0f, 0xf0])
-                     ~?= ShortByteString.pack [0x0f, 0xf0]
-                   ]
-            , "TryFrom ByteString Text"
-              ~: let f = hush . Witch.tryFrom @ByteString.ByteString @Text.Text
-                 in
-                   [ f (ByteString.pack []) ~?= Just (Text.pack "")
-                   , f (ByteString.pack [0x61]) ~?= Just (Text.pack "a")
-                   , f (ByteString.pack [0xff]) ~?= Nothing
-                   ]
-            , "TryFrom ByteString LazyText"
-              ~: let
-                   f =
-                     hush . Witch.tryFrom @ByteString.ByteString @LazyText.Text
-                 in
-                   [ f (ByteString.pack []) ~?= Just (LazyText.pack "")
-                   , f (ByteString.pack [0x61]) ~?= Just (LazyText.pack "a")
-                   , f (ByteString.pack [0xff]) ~?= Nothing
-                   ]
-            , "TryFrom ByteString String"
-              ~: let f = hush . Witch.tryFrom @ByteString.ByteString @String
-                 in
-                   [ f (ByteString.pack []) ~?= Just ""
-                   , f (ByteString.pack [0x61]) ~?= Just "a"
-                   , f (ByteString.pack [0xff]) ~?= Nothing
-                   ]
-
-    -- LazyByteString
-            , "From [Word8] LazyByteString"
-              ~: let f = Witch.from @[Word.Word8] @LazyByteString.ByteString
-                 in
-                   [ f [] ~?= LazyByteString.pack []
-                   , f [0x00] ~?= LazyByteString.pack [0x00]
-                   , f [0x0f, 0xf0] ~?= LazyByteString.pack [0x0f, 0xf0]
-                   ]
-            , "From LazyByteString [Word8]"
-              ~: let f = Witch.from @LazyByteString.ByteString @[Word.Word8]
-                 in
-                   [ f (LazyByteString.pack []) ~?= []
-                   , f (LazyByteString.pack [0x00]) ~?= [0x00]
-                   , f (LazyByteString.pack [0x0f, 0xf0]) ~?= [0x0f, 0xf0]
-                   ]
-            , "From LazyByteString ByteString"
-              ~: let
-                   f =
-                     Witch.from @LazyByteString.ByteString
-                       @ByteString.ByteString
-                 in
-                   [ f (LazyByteString.pack []) ~?= ByteString.pack []
-                   , f (LazyByteString.pack [0x00]) ~?= ByteString.pack [0x00]
-                   , f (LazyByteString.pack [0x0f, 0xf0])
-                     ~?= ByteString.pack [0x0f, 0xf0]
-                   ]
-            , "TryFrom LazyByteString LazyText"
-              ~: let
-                   f =
-                     hush
-                       . Witch.tryFrom @LazyByteString.ByteString @LazyText.Text
-                 in
-                   [ f (LazyByteString.pack []) ~?= Just (LazyText.pack "")
-                   , f (LazyByteString.pack [0x61]) ~?= Just (LazyText.pack "a")
-                   , f (LazyByteString.pack [0xff]) ~?= Nothing
-                   ]
-            , "TryFrom LazyByteString Text"
-              ~: let
-                   f =
-                     hush . Witch.tryFrom @LazyByteString.ByteString @Text.Text
-                 in
-                   [ f (LazyByteString.pack []) ~?= Just (Text.pack "")
-                   , f (LazyByteString.pack [0x61]) ~?= Just (Text.pack "a")
-                   , f (LazyByteString.pack [0xff]) ~?= Nothing
-                   ]
-            , "TryFrom LazyByteString String"
-              ~: let
-                   f = hush . Witch.tryFrom @LazyByteString.ByteString @String
-                 in
-                   [ f (LazyByteString.pack []) ~?= Just ""
-                   , f (LazyByteString.pack [0x61]) ~?= Just "a"
-                   , f (LazyByteString.pack [0xff]) ~?= Nothing
-                   ]
-
-    -- ShortByteString
-            , "From [Word8] ShortByteString"
-              ~: let
-                   f =
-                     Witch.from @[Word.Word8] @ShortByteString.ShortByteString
-                 in
-                   [ f [] ~?= ShortByteString.pack []
-                   , f [0x00] ~?= ShortByteString.pack [0x00]
-                   , f [0x0f, 0xf0] ~?= ShortByteString.pack [0x0f, 0xf0]
-                   ]
-            , "From ShortByteString [Word8]"
-              ~: let
-                   f =
-                     Witch.from @ShortByteString.ShortByteString @[Word.Word8]
-                 in
-                   [ f (ShortByteString.pack []) ~?= []
-                   , f (ShortByteString.pack [0x00]) ~?= [0x00]
-                   , f (ShortByteString.pack [0x0f, 0xf0]) ~?= [0x0f, 0xf0]
-                   ]
-            , "From ShortByteString ByteString"
-              ~: let
-                   f =
-                     Witch.from @ShortByteString.ShortByteString
-                       @ByteString.ByteString
-                 in
-                   [ f (ShortByteString.pack []) ~?= ByteString.pack []
-                   , f (ShortByteString.pack [0x00]) ~?= ByteString.pack [0x00]
-                   , f (ShortByteString.pack [0x0f, 0xf0])
-                     ~?= ByteString.pack [0x0f, 0xf0]
-                   ]
-
-    -- Text
-            , "From Text LazyText"
-              ~: let f = Witch.from @Text.Text @LazyText.Text
-                 in
-                   [ f (Text.pack "") ~?= LazyText.pack ""
-                   , f (Text.pack "a") ~?= LazyText.pack "a"
-                   , f (Text.pack "ab") ~?= LazyText.pack "ab"
-                   ]
-            , "From Text ByteString"
-              ~: let f = Witch.from @Text.Text @ByteString.ByteString
-                 in
-                   [ f (Text.pack "") ~?= ByteString.pack []
-                   , f (Text.pack "a") ~?= ByteString.pack [0x61]
-                   ]
-            , "From Text LazyByteString"
-              ~: let f = Witch.from @Text.Text @LazyByteString.ByteString
-                 in
-                   [ f (Text.pack "") ~?= LazyByteString.pack []
-                   , f (Text.pack "a") ~?= LazyByteString.pack [0x61]
-                   ]
-
-    -- LazyText
-            , "From LazyText Text"
-              ~: let f = Witch.from @LazyText.Text @Text.Text
-                 in
-                   [ f (LazyText.pack "") ~?= Text.pack ""
-                   , f (LazyText.pack "a") ~?= Text.pack "a"
-                   , f (LazyText.pack "ab") ~?= Text.pack "ab"
-                   ]
-            , "From LazyText LazyByteString"
-              ~: let f = Witch.from @LazyText.Text @LazyByteString.ByteString
-                 in
-                   [ f (LazyText.pack "") ~?= LazyByteString.pack []
-                   , f (LazyText.pack "a") ~?= LazyByteString.pack [0x61]
-                   ]
-            , "From LazyText ByteString"
-              ~: let f = Witch.from @LazyText.Text @ByteString.ByteString
-                 in
-                   [ f (LazyText.pack "") ~?= ByteString.pack []
-                   , f (LazyText.pack "a") ~?= ByteString.pack [0x61]
-                   ]
-
-    -- String
-            , "From String Text"
-              ~: let f = Witch.from @String @Text.Text
-                 in
-                   [ f "" ~?= Text.pack ""
-                   , f "a" ~?= Text.pack "a"
-                   , f "ab" ~?= Text.pack "ab"
-                   ]
-            , "From Text String"
-              ~: let f = Witch.from @Text.Text @String
-                 in
-                   [ f (Text.pack "") ~?= ""
-                   , f (Text.pack "a") ~?= "a"
-                   , f (Text.pack "ab") ~?= "ab"
-                   ]
-            , "From String LazyText"
-              ~: let f = Witch.from @String @LazyText.Text
-                 in
-                   [ f "" ~?= LazyText.pack ""
-                   , f "a" ~?= LazyText.pack "a"
-                   , f "ab" ~?= LazyText.pack "ab"
-                   ]
-            , "From LazyText String"
-              ~: let f = Witch.from @LazyText.Text @String
-                 in
-                   [ f (LazyText.pack "") ~?= ""
-                   , f (LazyText.pack "a") ~?= "a"
-                   , f (LazyText.pack "ab") ~?= "ab"
-                   ]
-            , "From String ByteString"
-              ~: let f = Witch.from @String @ByteString.ByteString
-                 in
-                   [ f "" ~?= ByteString.pack []
-                   , f "a" ~?= ByteString.pack [0x61]
-                   ]
-            , "From String LazyByteString"
-              ~: let f = Witch.from @String @LazyByteString.ByteString
-                 in
-                   [ f "" ~?= LazyByteString.pack []
-                   , f "a" ~?= LazyByteString.pack [0x61]
-                   ]
-
-    -- Day
-            , "From Integer Day"
-              ~: let f = Witch.from @Integer @Time.Day
-                 in [f 0 ~?= Time.ModifiedJulianDay 0]
-            , "From Day Integer"
-              ~: let f = Witch.from @Time.Day @Integer
-                 in [f (Time.ModifiedJulianDay 0) ~?= 0]
-
-    -- DayOfWeek
-            , "From Day DayOfWeek"
-              ~: let f = Witch.from @Time.Day @Time.DayOfWeek
-                 in [f (Time.ModifiedJulianDay 0) ~?= Time.Wednesday]
-
-    -- UniversalTime
-            , "From Rational UniversalTime"
-              ~: let f = Witch.from @Rational @Time.UniversalTime
-                 in [f 0 ~?= Time.ModJulianDate 0]
-            , "From UniversalTime Rational"
-              ~: let f = Witch.from @Time.UniversalTime @Rational
-                 in [f (Time.ModJulianDate 0) ~?= 0]
-
-    -- DiffTime
-            , "From Pico DiffTime"
-              ~: let f = Witch.from @Fixed.Pico @Time.DiffTime in [f 0 ~?= 0]
-            , "From DiffTime Pico"
-              ~: let f = Witch.from @Time.DiffTime @Fixed.Pico in [f 0 ~?= 0]
-
-    -- NominalDiffTime
-            , "From Pico NominalDiffTime"
-              ~: let f = Witch.from @Fixed.Pico @Time.NominalDiffTime
-                 in [f 0 ~?= 0]
-            , "From NominalDiffTime Pico"
-              ~: let f = Witch.from @Time.NominalDiffTime @Fixed.Pico
-                 in [f 0 ~?= 0]
-
-    -- POSIXTime
-            , "From SystemTime POSIXTime"
-              ~: let f = Witch.from @Time.SystemTime @Time.POSIXTime
-                 in [f (Time.MkSystemTime 0 0) ~?= 0]
-            , "From UTCTime POSIXTime"
-              ~: let f = Witch.from @Time.UTCTime @Time.POSIXTime
-                 in [f unixEpoch ~?= 0]
-            , "From POSIXTime UTCTime"
-              ~: let f = Witch.from @Time.POSIXTime @Time.UTCTime
-                 in [f 0 ~?= unixEpoch]
-
-    -- SystemTime
-            , "From UTCTime SystemTime"
-              ~: let f = Witch.from @Time.UTCTime @Time.SystemTime
-                 in [f unixEpoch ~?= Time.MkSystemTime 0 0]
-            , "From SystemTime AbsoluteTime"
-              ~: let f = Witch.from @Time.SystemTime @Time.AbsoluteTime
-                 in [f (Time.MkSystemTime (-3506716800) 0) ~?= Time.taiEpoch]
-            , "From SystemTime UTCTime"
-              ~: let f = Witch.from @Time.SystemTime @Time.UTCTime
-                 in [f (Time.MkSystemTime 0 0) ~?= unixEpoch]
-
-    -- TimeOfDay
-            , "From DiffTime TimeOfDay"
-              ~: let f = Witch.from @Time.DiffTime @Time.TimeOfDay
-                 in [f 0 ~?= Time.TimeOfDay 0 0 0]
-            , "From Rational TimeOfDay"
-              ~: let f = Witch.from @Rational @Time.TimeOfDay
-                 in [f 0 ~?= Time.TimeOfDay 0 0 0]
-            , "From TimeOfDay DiffTime"
-              ~: let f = Witch.from @Time.TimeOfDay @Time.DiffTime
-                 in [f (Time.TimeOfDay 0 0 0) ~?= 0]
-            , "From TimeOfDay Rational"
-              ~: let f = Witch.from @Time.TimeOfDay @Rational
-                 in [f (Time.TimeOfDay 0 0 0) ~?= 0]
-
-    -- CalendarDiffTime
-            , "From CalendarDiffDays CalendarDiffTime"
-              ~: let
-                   f = Witch.from @Time.CalendarDiffDays @Time.CalendarDiffTime
-                 in
-                   [f (Time.CalendarDiffDays 0 0) ~?= Time.CalendarDiffTime 0 0]
-            , "From NominalDiffTime CalendarDiffTime"
-              ~: let
-                   f = Witch.from @Time.NominalDiffTime @Time.CalendarDiffTime
-                 in [f 0 ~?= Time.CalendarDiffTime 0 0]
-
-    -- ZonedTime
-            , "From ZonedTime UTCTime"
-              ~: let f = Witch.from @Time.ZonedTime @Time.UTCTime
-                 in
-                   [ f
-                         (Time.ZonedTime
-                           (Time.LocalTime
-                             (Time.ModifiedJulianDay 0)
-                             (Time.TimeOfDay 0 0 0)
-                           )
-                           Time.utc
-                         )
-                       ~?= Time.UTCTime (Time.ModifiedJulianDay 0) 0
-                   ]
-            ]
-       ]
-
-unixEpoch :: Time.UTCTime
-unixEpoch = Time.UTCTime (Time.ModifiedJulianDay 40587) 0
-
-hush :: Either x a -> Maybe a
-hush = either (const Nothing) Just
-
-newtype Age
-  = Age Int.Int8
-  deriving (Eq, Show)
-
-instance Witch.From Age Int.Int8
-
-instance Witch.From Int.Int8 Age
diff --git a/witch.cabal b/witch.cabal
--- a/witch.cabal
+++ b/witch.cabal
@@ -1,15 +1,15 @@
 cabal-version: 2.2
 
 name: witch
-version: 0.3.4.2
+version: 1.0.0.1
 synopsis: Convert values from one type into another.
 description: Witch converts values from one type into another.
 
 build-type: Simple
 category: Data
 extra-source-files: CHANGELOG.markdown README.markdown
-license-file: LICENSE.txt
-license: ISC
+license-file: LICENSE.markdown
+license: MIT
 maintainer: Taylor Fausak
 
 source-repository head
@@ -21,11 +21,12 @@
   description: Enables @-Werror@, which turns warnings into errors.
   manual: True
 
-common basics
+common library
   build-depends:
     , base >= 4.10.0 && < 4.17
     , bytestring >= 0.10.8 && < 0.12
     , containers >= 0.5.10 && < 0.7
+    , template-haskell >= 2.12.0 && < 2.19
     , text >= 1.2.3 && < 1.3
     , time >= 1.9.1 && < 1.13
   default-language: Haskell2010
@@ -60,11 +61,21 @@
     ghc-options:
       -Werror
 
+common executable
+  import: library
+
+  build-depends: witch
+  ghc-options:
+    -rtsopts
+    -threaded
+
+  if impl(ghc >= 8.10)
+    ghc-options:
+      -Wno-unused-packages
+
 library
-  import: basics
+  import: library
 
-  build-depends:
-    , template-haskell >= 2.12.0 && < 2.19
   exposed-modules:
     Witch
     Witch.From
@@ -73,26 +84,20 @@
     Witch.TryFrom
     Witch.TryFromException
     Witch.Utility
-  hs-source-dirs: src/lib
+  hs-source-dirs: source/library
 
   if impl(ghc >= 9.0)
-    hs-source-dirs: src/ghc-9.0
+    hs-source-dirs: source/ghc-9.0
+  elif impl(ghc >= 8.10)
+    hs-source-dirs: source/ghc-8.10
   else
-    if impl(ghc >= 8.10)
-      hs-source-dirs: src/ghc-8.10
-    else
-      hs-source-dirs: src/ghc-8.8
+    hs-source-dirs: source/ghc-8.8
 
 test-suite test
-  import: basics
+  import: executable
 
   build-depends:
-    , HUnit >= 1.6.2 && < 1.7
-    , witch
-  ghc-options:
-    -rtsopts
-    -threaded
-    -Wno-all-missed-specialisations
-  hs-source-dirs: src/test
+    , HUnit >= 1.6.1 && < 1.7
+  hs-source-dirs: source/test-suite
   main-is: Main.hs
   type: exitcode-stdio-1.0
