diff --git a/src/ghc-8.10/Witch/Lift.hs b/src/ghc-8.10/Witch/Lift.hs
--- a/src/ghc-8.10/Witch/Lift.hs
+++ b/src/ghc-8.10/Witch/Lift.hs
@@ -1,35 +1,12 @@
-{-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE ExplicitForAll #-}
-{-# LANGUAGE TypeFamilies #-}
 
 module Witch.Lift where
 
 import qualified Data.Typeable as Typeable
 import qualified Language.Haskell.TH.Syntax as TH
-import qualified Witch.Identity as Identity
-import qualified Witch.TryCast as TryCast
+import qualified Witch.TryFrom as TryFrom
 import qualified Witch.Utility as Utility
 
--- | This is like 'Utility.unsafeCast' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeCast "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedCast "some literal")
-liftedCast
-  :: forall source target
-   . ( TryCast.TryCast source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> TH.Q (TH.TExp target)
-liftedCast = TH.liftTyped . Utility.unsafeCast
-
 -- | This is like 'Utility.unsafeFrom' except that it works at compile time
 -- rather than runtime.
 --
@@ -39,9 +16,8 @@
 -- > -- Prefer this:
 -- > $$(liftedFrom @s "some literal")
 liftedFrom
-  :: forall s target source
-   . ( Identity.Identity s ~ source
-     , TryCast.TryCast source target
+  :: forall source target
+   . ( TryFrom.TryFrom source target
      , TH.Lift target
      , Show source
      , Typeable.Typeable source
@@ -49,7 +25,7 @@
      )
   => source
   -> TH.Q (TH.TExp target)
-liftedFrom = liftedCast
+liftedFrom = TH.liftTyped . Utility.unsafeFrom
 
 -- | This is like 'Utility.unsafeInto' except that it works at compile time
 -- rather than runtime.
@@ -60,9 +36,8 @@
 -- > -- Prefer this:
 -- > $$(liftedInto @t "some literal")
 liftedInto
-  :: forall t source target
-   . ( Identity.Identity t ~ target
-     , TryCast.TryCast source target
+  :: forall target source
+   . ( TryFrom.TryFrom source target
      , TH.Lift target
      , Show source
      , Typeable.Typeable source
@@ -70,4 +45,4 @@
      )
   => source
   -> TH.Q (TH.TExp target)
-liftedInto = liftedCast
+liftedInto = liftedFrom
diff --git a/src/ghc-8.8/Witch/Lift.hs b/src/ghc-8.8/Witch/Lift.hs
--- a/src/ghc-8.8/Witch/Lift.hs
+++ b/src/ghc-8.8/Witch/Lift.hs
@@ -1,35 +1,12 @@
-{-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
 
 module Witch.Lift where
 
 import qualified Data.Typeable as Typeable
 import qualified Language.Haskell.TH.Syntax as TH
-import qualified Witch.Identity as Identity
-import qualified Witch.TryCast as TryCast
+import qualified Witch.TryFrom as TryFrom
 import qualified Witch.Utility as Utility
 
--- | This is like 'Utility.unsafeCast' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeCast "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedCast "some literal")
-liftedCast
-  :: forall source target
-   . ( TryCast.TryCast source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> TH.Q (TH.TExp target)
-liftedCast s = TH.unsafeTExpCoerce $ TH.lift (Utility.unsafeCast s :: target)
-
 -- | This is like 'Utility.unsafeFrom' except that it works at compile time
 -- rather than runtime.
 --
@@ -39,9 +16,8 @@
 -- > -- Prefer this:
 -- > $$(liftedFrom @s "some literal")
 liftedFrom
-  :: forall s target source
-   . ( Identity.Identity s ~ source
-     , TryCast.TryCast source target
+  :: forall source target
+   . ( TryFrom.TryFrom source target
      , TH.Lift target
      , Show source
      , Typeable.Typeable source
@@ -49,7 +25,7 @@
      )
   => source
   -> TH.Q (TH.TExp target)
-liftedFrom = liftedCast
+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.
@@ -60,9 +36,8 @@
 -- > -- Prefer this:
 -- > $$(liftedInto @t "some literal")
 liftedInto
-  :: forall t source target
-   . ( Identity.Identity t ~ target
-     , TryCast.TryCast source target
+  :: forall target source
+   . ( TryFrom.TryFrom source target
      , TH.Lift target
      , Show source
      , Typeable.Typeable source
@@ -70,4 +45,4 @@
      )
   => source
   -> TH.Q (TH.TExp target)
-liftedInto = liftedCast
+liftedInto = liftedFrom
diff --git a/src/ghc-9.0/Witch/Lift.hs b/src/ghc-9.0/Witch/Lift.hs
--- a/src/ghc-9.0/Witch/Lift.hs
+++ b/src/ghc-9.0/Witch/Lift.hs
@@ -1,36 +1,12 @@
-{-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE ExplicitForAll #-}
-{-# LANGUAGE TypeFamilies #-}
 
 module Witch.Lift where
 
 import qualified Data.Typeable as Typeable
 import qualified Language.Haskell.TH.Syntax as TH
-import qualified Witch.Identity as Identity
-import qualified Witch.TryCast as TryCast
+import qualified Witch.TryFrom as TryFrom
 import qualified Witch.Utility as Utility
 
--- | This is like 'Utility.unsafeCast' except that it works at compile time
--- rather than runtime.
---
--- > -- Avoid this:
--- > unsafeCast "some literal"
--- >
--- > -- Prefer this:
--- > $$(liftedCast "some literal")
-liftedCast
-  :: forall source target m
-   . ( TryCast.TryCast source target
-     , TH.Lift target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     , TH.Quote m
-     )
-  => source
-  -> TH.Code m target
-liftedCast = TH.liftTyped . Utility.unsafeCast
-
 -- | This is like 'Utility.unsafeFrom' except that it works at compile time
 -- rather than runtime.
 --
@@ -40,9 +16,8 @@
 -- > -- Prefer this:
 -- > $$(liftedFrom @s "some literal")
 liftedFrom
-  :: forall s target m source
-   . ( Identity.Identity s ~ source
-     , TryCast.TryCast source target
+  :: forall source target m
+   . ( TryFrom.TryFrom source target
      , TH.Lift target
      , Show source
      , Typeable.Typeable source
@@ -51,7 +26,7 @@
      )
   => source
   -> TH.Code m target
-liftedFrom = liftedCast
+liftedFrom = TH.liftTyped . Utility.unsafeFrom
 
 -- | This is like 'Utility.unsafeInto' except that it works at compile time
 -- rather than runtime.
@@ -62,9 +37,8 @@
 -- > -- Prefer this:
 -- > $$(liftedInto @t "some literal")
 liftedInto
-  :: forall t source m target
-   . ( Identity.Identity t ~ target
-     , TryCast.TryCast source target
+  :: forall target source m
+   . ( TryFrom.TryFrom source target
      , TH.Lift target
      , Show source
      , Typeable.Typeable source
@@ -73,4 +47,4 @@
      )
   => source
   -> TH.Code m target
-liftedInto = liftedCast
+liftedInto = liftedFrom
diff --git a/src/lib/Witch.hs b/src/lib/Witch.hs
--- a/src/lib/Witch.hs
+++ b/src/lib/Witch.hs
@@ -6,19 +6,17 @@
 -- >>> import Witch
 --
 -- In typical usage, you will most likely use 'Witch.Utility.into' for
--- 'Witch.Cast.Cast' instances and 'With.Utility.tryInto' for
--- 'Witch.TryCast.TryCast' instances.
+-- 'Witch.From.From' instances and 'With.Utility.tryInto' for
+-- 'Witch.TryFrom.TryFrom' instances.
 module Witch
   ( -- * Type classes
 
-  -- ** Cast
-    Witch.Cast.Cast(cast)
-  , Witch.Utility.from
+  -- ** From
+    Witch.From.From(from)
   , Witch.Utility.into
 
-  -- ** TryCast
-  , Witch.TryCast.TryCast(tryCast)
-  , Witch.Utility.tryFrom
+  -- ** TryFrom
+  , Witch.TryFrom.TryFrom(tryFrom)
   , Witch.Utility.tryInto
 
   -- * Utilities
@@ -26,18 +24,17 @@
   , Witch.Utility.over
   , Witch.Utility.via
   , Witch.Utility.tryVia
-  , Witch.Utility.maybeTryCast
-  , Witch.Utility.eitherTryCast
+  , 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.Cast.cast'. And if you're converting a literal value, consider
-  -- using the Template Haskell conversion functions like
-  -- 'Witch.Lift.liftedCast'.
-  , Witch.Utility.unsafeCast
+  -- '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
 
@@ -48,15 +45,11 @@
   -- 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.liftedCast
   , Witch.Lift.liftedFrom
   , Witch.Lift.liftedInto
 
   -- * Data types
-  , Witch.TryCastException.TryCastException(..)
-
-  -- ** Casting
-  , Witch.Casting.Casting(Casting)
+  , Witch.TryFromException.TryFromException(..)
 
   -- * Notes
 
@@ -68,8 +61,8 @@
   -- pitfalls to watch out for.
   --
   -- This library tries to address that problem by providing a common
-  -- interface for converting between types. The 'Witch.Cast.Cast' type class
-  -- is for conversions that cannot fail, and the 'Witch.TryCast.TryCast' type
+  -- 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.
@@ -123,7 +116,7 @@
   --   negative 'Int' into a 'Word' will overflow, which may be surprising.
 
   -- ** Instances
-  -- | When should you add a 'Witch.Cast.Cast' (or 'Witch.TryCast.TryCast')
+  -- | 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.
   --
@@ -132,70 +125,41 @@
   --
   -- - Conversions should be unambiguous. If there are multiple reasonable
   --   ways to convert from @a@ to @b@, then you probably should not add a
-  --   @Cast@ instance for them.
+  --   'Witch.From.From' instance for them.
   --
-  -- - Conversions should be lossless. If you have @Cast a b@ then no two @a@
+  -- - 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 @Cast a b@ and @Cast b a@, then
-  --   @cast \@b \@a . cast \@a \@b@ should be the same as 'id'. In other
+  -- - 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 @Cast a b@ and @Cast b c@, then you could also have
-  --   @Cast a c@ and it should be the same as @cast \@b \@c . cast \@a \@b@.
-  --   In other words, @Cast@ is transitive.
+  -- - 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@.
   --
-  -- In general if @s@ /is/ a @t@, then you should add a 'Witch.Cast.Cast'
+  -- 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.TryCast.TryCast' instance for it. And if it is technically
+  -- '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.
-
-  -- ** Type applications
-  -- | This library is designed to be used with the [@TypeApplications@](https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/exts/type_applications.html)
-  -- language extension. Although it is not required for basic functionality,
-  -- it is strongly encouraged. You can use 'Witch.Cast.cast',
-  -- 'Witch.TryCast.tryCast', 'Witch.Utility.unsafeCast', and
-  -- 'Witch.Lift.liftedCast' without type applications. Everything else
-  -- requires a type application.
-
-  -- ** Ambiguous types
-  -- | You may see @Identity@ show up in some type signatures. Anywhere you see
-  -- @Identity a@, you can mentally replace it with @a@. It is a type family
-  -- used to trick GHC into requiring type applications for certain functions.
-  -- If you forget to give a type application, you will see an error like
-  -- this:
-  --
-  -- >>> from (1 :: Int8) :: Int16
-  -- <interactive>:1:1: error:
-  --     * Couldn't match type `Identity s0' with `Int8'
-  --         arising from a use of `from'
-  --       The type variable `s0' is ambiguous
-  --     * In the expression: from (1 :: Int8) :: Int16
-  --       In an equation for `it': it = from (1 :: Int8) :: Int16
-  --
-  -- You can fix the problem by giving a type application:
-  --
-  -- >>> from @Int8 1 :: Int16
-  -- 1
   ) where
 
-import qualified Witch.Cast
-import qualified Witch.Casting
+import qualified Witch.From
 import Witch.Instances ()
 import qualified Witch.Lift
-import qualified Witch.TryCast
-import qualified Witch.TryCastException
+import qualified Witch.TryFrom
+import qualified Witch.TryFromException
 import qualified Witch.Utility
diff --git a/src/lib/Witch/Cast.hs b/src/lib/Witch/Cast.hs
deleted file mode 100644
--- a/src/lib/Witch/Cast.hs
+++ /dev/null
@@ -1,31 +0,0 @@
-{-# LANGUAGE DefaultSignatures #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module Witch.Cast 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 @Cast source target@ measn that
--- you can convert from a value of type @source@ into a value of type
--- @target@.
---
--- This type class is for conversions that cannot fail. If your conversion can
--- fail, consider implementing @TryCast@ instead.
-class Cast source target where
-  -- | This method implements the conversion of a value between types. At call
-  -- sites you will usually want to use @from@ or @into@ instead of this
-  -- method.
-  --
-  -- 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 Cast Name String
-  -- >>> instance Cast String Name
-  cast :: source -> target
-
-  default cast :: Coerce.Coercible source target => source -> target
-  cast = Coerce.coerce
diff --git a/src/lib/Witch/Casting.hs b/src/lib/Witch/Casting.hs
deleted file mode 100644
--- a/src/lib/Witch/Casting.hs
+++ /dev/null
@@ -1,62 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeApplications #-}
-
-module Witch.Casting where
-
-import qualified Data.Bifunctor as Bifunctor
-import qualified Data.Function as Function
-import qualified Witch.Cast as Cast
-
--- | This type mostly exists to make it easier to derive instances through
--- some other type. It does this by leaning on the 'Cast.Cast' type class. For
--- example, consider this data type:
---
--- > data Toggle = Off | On
--- > instance Cast Toggle String where
--- >   cast toggle = case toggle of
--- >     Off -> "off"
--- >     On -> "on"
---
--- If you wanted to implement a 'Show' instance for @Toggle@ by going through
--- a 'String', you would need to write something like this:
---
--- > instance Show Toggle where
--- >   show = show . into @String
---
--- That may not very complicated, but at the same time it is not very
--- interesting. And it can be tricky if you want to keep other instances (like
--- 'Read') in sync. That's where the 'Casting' type comes in! You can
--- derive the above instance like so:
---
--- > data Toggle = Off | On
--- >   deriving Show via Casting Toggle String
-newtype Casting source target
-  = Casting source
-
--- | Uses @coerce@.
-instance Cast.Cast s (Casting s t)
-
--- | Uses @coerce@.
-instance Cast.Cast (Casting s t) s
-
-instance (Cast.Cast t s, Bounded t) => Bounded (Casting s t) where
-  maxBound = Cast.cast $ Cast.cast @t @s maxBound
-  minBound = Cast.cast $ Cast.cast @t @s minBound
-
-instance (Cast.Cast s t, Cast.Cast t s, Enum t) => Enum (Casting s t) where
-  fromEnum = fromEnum . Cast.cast @s @t . Cast.cast
-  toEnum = Cast.cast . Cast.cast @t @s . toEnum
-
-instance (Cast.Cast s t, Eq t) => Eq (Casting s t) where
-  (==) = Function.on (==) $ Cast.cast @s @t . Cast.cast
-
-instance (Cast.Cast s t, Ord t) => Ord (Casting s t) where
-  compare = Function.on compare $ Cast.cast @s @t . Cast.cast
-
-instance (Cast.Cast t s, Read t) => Read (Casting s t) where
-  readsPrec = fmap (fmap . Bifunctor.first $ Cast.cast . Cast.cast @t @s) . readsPrec
-
-instance (Cast.Cast s t, Show t) => Show (Casting s t) where
-  show = show . Cast.cast @s @t . Cast.cast
diff --git a/src/lib/Witch/From.hs b/src/lib/Witch/From.hs
new file mode 100644
--- /dev/null
+++ b/src/lib/Witch/From.hs
@@ -0,0 +1,30 @@
+{-# 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 cannot fail. If your conversion can
+-- fail, consider implementing @TryFrom@ instead.
+class From source target where
+  -- | This method implements the conversion of a value between types. At call
+  -- sites you will usually want to use @into@ instead of this method.
+  --
+  -- 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/Identity.hs b/src/lib/Witch/Identity.hs
deleted file mode 100644
--- a/src/lib/Witch/Identity.hs
+++ /dev/null
@@ -1,14 +0,0 @@
-{-# LANGUAGE TypeFamilies #-}
-
-module Witch.Identity where
-
--- | This is an ugly hack used to make GHC require type applications for
--- certain functions. See this Twitter thread for a discussion:
--- <https://twitter.com/taylorfausak/status/1329084033003782148>.
-type family Identity a where
-  Identity Never = ()
-  Identity a = a
-
--- | Never use this type for anything! It only exists to make the 'Identity'
--- type family non-trivial.
-data Never
diff --git a/src/lib/Witch/Instances.hs b/src/lib/Witch/Instances.hs
--- a/src/lib/Witch/Instances.hs
+++ b/src/lib/Witch/Instances.hs
@@ -1,8 +1,6 @@
 {-# OPTIONS_GHC -Wno-orphans #-}
-{-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeApplications #-}
 
 module Witch.Instances where
@@ -27,232 +25,231 @@
 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.Typeable as Typeable
 import qualified Data.Word as Word
 import qualified GHC.Float as Float
 import qualified Numeric.Natural as Natural
-import qualified Witch.Cast as Cast
-import qualified Witch.TryCast as TryCast
-import qualified Witch.TryCastException as TryCastException
+import qualified Witch.From as From
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.TryFromException as TryFromException
 import qualified Witch.Utility as Utility
 
 -- Int8
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Int.Int16 where
-  cast = fromIntegral
+instance From.From Int.Int8 Int.Int16 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Int.Int32 where
-  cast = fromIntegral
+instance From.From Int.Int8 Int.Int32 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Int.Int64 where
-  cast = fromIntegral
+instance From.From Int.Int8 Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Int where
-  cast = fromIntegral
+instance From.From Int.Int8 Int where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Integer where
-  cast = fromIntegral
+instance From.From Int.Int8 Integer where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int8 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int8 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int8 Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int8 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int8 Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int8 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int8 Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int8 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int8 Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int8 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral' when the input is not negative.
-instance TryCast.TryCast Int.Int8 Natural.Natural where
-  tryCast = Utility.eitherTryCast fromNonNegativeIntegral
+instance TryFrom.TryFrom Int.Int8 Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Float where
-  cast = fromIntegral
+instance From.From Int.Int8 Float where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int8 Double where
-  cast = fromIntegral
+instance From.From Int.Int8 Double where
+  from = fromIntegral
 
 -- Int16
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int16 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int16 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int16 Int.Int32 where
-  cast = fromIntegral
+instance From.From Int.Int16 Int.Int32 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int16 Int.Int64 where
-  cast = fromIntegral
+instance From.From Int.Int16 Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int16 Int where
-  cast = fromIntegral
+instance From.From Int.Int16 Int where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int16 Integer where
-  cast = fromIntegral
+instance From.From Int.Int16 Integer where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int16 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int16 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int16 Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int16 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int16 Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int16 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int16 Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int16 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int16 Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int16 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral' when the input is not negative.
-instance TryCast.TryCast Int.Int16 Natural.Natural where
-  tryCast = Utility.eitherTryCast fromNonNegativeIntegral
+instance TryFrom.TryFrom Int.Int16 Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int16 Float where
-  cast = fromIntegral
+instance From.From Int.Int16 Float where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int16 Double where
-  cast = fromIntegral
+instance From.From Int.Int16 Double where
+  from = fromIntegral
 
 -- Int32
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int32 Int.Int64 where
-  cast = fromIntegral
+instance From.From Int.Int32 Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int32 Integer where
-  cast = fromIntegral
+instance From.From Int.Int32 Integer where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int32 Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int32 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral' when the input is not negative.
-instance TryCast.TryCast Int.Int32 Natural.Natural where
-  tryCast = Utility.eitherTryCast fromNonNegativeIntegral
+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 TryCast.TryCast Int.Int32 Float where
-  tryCast = Utility.eitherTryCast $ \s -> if s < -maxFloat
+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 Cast.Cast Int.Int32 Double where
-  cast = fromIntegral
+instance From.From Int.Int32 Double where
+  from = fromIntegral
 
 -- Int64
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int.Int64 Integer where
-  cast = fromIntegral
+instance From.From Int.Int64 Integer where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int.Int64 Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int.Int64 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral' when the input is not negative.
-instance TryCast.TryCast Int.Int64 Natural.Natural where
-  tryCast = Utility.eitherTryCast fromNonNegativeIntegral
+instance TryFrom.TryFrom Int.Int64 Natural.Natural where
+  tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral
 
 -- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215
 -- inclusive.
-instance TryCast.TryCast Int.Int64 Float where
-  tryCast = Utility.eitherTryCast $ \s -> if s < -maxFloat
+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
@@ -260,8 +257,8 @@
 
 -- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
 -- 9,007,199,254,740,991 inclusive.
-instance TryCast.TryCast Int.Int64 Double where
-  tryCast = Utility.eitherTryCast $ \s -> if s < -maxDouble
+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
@@ -270,53 +267,53 @@
 -- Int
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int Int.Int64 where
-  cast = fromIntegral
+instance From.From Int Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Int Integer where
-  cast = fromIntegral
+instance From.From Int Integer where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Int Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Int Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral' when the input is not negative.
-instance TryCast.TryCast Int Natural.Natural where
-  tryCast = Utility.eitherTryCast fromNonNegativeIntegral
+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 TryCast.TryCast Int Float where
-  tryCast = Utility.eitherTryCast $ \s -> if s < -maxFloat
+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
@@ -324,8 +321,8 @@
 
 -- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
 -- 9,007,199,254,740,991 inclusive.
-instance TryCast.TryCast Int Double where
-  tryCast = Utility.eitherTryCast $ \s ->
+instance TryFrom.TryFrom Int Double where
+  tryFrom = Utility.eitherTryFrom $ \s ->
     if toInteger (maxBound :: Int) <= maxDouble
       then Right $ fromIntegral s
       else if s < -maxDouble
@@ -337,58 +334,58 @@
 -- Integer
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Int.Int64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Integer Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Integer Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromInteger' when the input is not negative.
-instance TryCast.TryCast Integer Natural.Natural where
-  -- This should use @eitherTryCast fromNonNegativeIntegral@, but that causes
+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
-  tryCast = Utility.eitherTryCast
+  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 TryCast.TryCast Integer Float where
-  tryCast = Utility.eitherTryCast $ \s -> if s < -maxFloat
+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
@@ -396,8 +393,8 @@
 
 -- | Uses 'fromIntegral' when the input is between -9,007,199,254,740,991 and
 -- 9,007,199,254,740,991 inclusive.
-instance TryCast.TryCast Integer Double where
-  tryCast = Utility.eitherTryCast $ \s -> if s < -maxDouble
+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
@@ -406,279 +403,279 @@
 -- Word8
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Word.Word16 where
-  cast = fromIntegral
+instance From.From Word.Word8 Word.Word16 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Word.Word32 where
-  cast = fromIntegral
+instance From.From Word.Word8 Word.Word32 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Word.Word64 where
-  cast = fromIntegral
+instance From.From Word.Word8 Word.Word64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Word where
-  cast = fromIntegral
+instance From.From Word.Word8 Word where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Natural.Natural where
-  cast = fromIntegral
+instance From.From Word.Word8 Natural.Natural where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word8 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word8 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Int.Int16 where
-  cast = fromIntegral
+instance From.From Word.Word8 Int.Int16 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Int.Int32 where
-  cast = fromIntegral
+instance From.From Word.Word8 Int.Int32 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Int.Int64 where
-  cast = fromIntegral
+instance From.From Word.Word8 Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Int where
-  cast = fromIntegral
+instance From.From Word.Word8 Int where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Integer where
-  cast = fromIntegral
+instance From.From Word.Word8 Integer where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Float where
-  cast = fromIntegral
+instance From.From Word.Word8 Float where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word8 Double where
-  cast = fromIntegral
+instance From.From Word.Word8 Double where
+  from = fromIntegral
 
 -- Word16
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word16 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word16 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Word.Word32 where
-  cast = fromIntegral
+instance From.From Word.Word16 Word.Word32 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Word.Word64 where
-  cast = fromIntegral
+instance From.From Word.Word16 Word.Word64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Word where
-  cast = fromIntegral
+instance From.From Word.Word16 Word where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Natural.Natural where
-  cast = fromIntegral
+instance From.From Word.Word16 Natural.Natural where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word16 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word16 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word16 Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word16 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Int.Int32 where
-  cast = fromIntegral
+instance From.From Word.Word16 Int.Int32 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Int.Int64 where
-  cast = fromIntegral
+instance From.From Word.Word16 Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Int where
-  cast = fromIntegral
+instance From.From Word.Word16 Int where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Integer where
-  cast = fromIntegral
+instance From.From Word.Word16 Integer where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Float where
-  cast = fromIntegral
+instance From.From Word.Word16 Float where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word16 Double where
-  cast = fromIntegral
+instance From.From Word.Word16 Double where
+  from = fromIntegral
 
 -- Word32
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word32 Word.Word64 where
-  cast = fromIntegral
+instance From.From Word.Word32 Word.Word64 where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word32 Natural.Natural where
-  cast = fromIntegral
+instance From.From Word.Word32 Natural.Natural where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word32 Int.Int64 where
-  cast = fromIntegral
+instance From.From Word.Word32 Int.Int64 where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word32 Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word32 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word32 Integer where
-  cast = 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 TryCast.TryCast Word.Word32 Float where
-  tryCast = Utility.eitherTryCast $ \s ->
+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 Cast.Cast Word.Word32 Double where
-  cast = fromIntegral
+instance From.From Word.Word32 Double where
+  from = fromIntegral
 
 -- Word64
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word64 Natural.Natural where
-  cast = fromIntegral
+instance From.From Word.Word64 Natural.Natural where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Int.Int64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word.Word64 Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word.Word64 Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word.Word64 Integer where
-  cast = 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 TryCast.TryCast Word.Word64 Float where
-  tryCast = Utility.eitherTryCast $ \s ->
+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 TryCast.TryCast Word.Word64 Double where
-  tryCast = Utility.eitherTryCast $ \s -> if s <= maxDouble
+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 TryCast.TryCast Word Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word Word.Word64 where
-  cast = fromIntegral
+instance From.From Word Word.Word64 where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word Natural.Natural where
-  cast = fromIntegral
+instance From.From Word Natural.Natural where
+  from = fromIntegral
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Int.Int64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Word Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Word Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Word Integer where
-  cast = fromIntegral
+instance From.From Word Integer where
+  from = fromIntegral
 
 -- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215.
-instance TryCast.TryCast Word Float where
-  tryCast = Utility.eitherTryCast $ \s ->
+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 TryCast.TryCast Word Double where
-  tryCast = Utility.eitherTryCast $ \s ->
+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
@@ -686,87 +683,87 @@
 -- Natural
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Word.Word8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Word.Word8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Word.Word16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Word.Word16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Word.Word32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Word.Word32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Word.Word64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Word.Word64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Word where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Word where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Int.Int8 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Int.Int8 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Int.Int16 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Int.Int16 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Int.Int32 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Int.Int32 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Int.Int64 where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Int.Int64 where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'Bits.toIntegralSized'.
-instance TryCast.TryCast Natural.Natural Int where
-  tryCast = Utility.maybeTryCast Bits.toIntegralSized
+instance TryFrom.TryFrom Natural.Natural Int where
+  tryFrom = Utility.maybeTryFrom Bits.toIntegralSized
 
 -- | Uses 'fromIntegral'.
-instance Cast.Cast Natural.Natural Integer where
-  cast = 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 TryCast.TryCast Natural.Natural Float where
-  tryCast = Utility.eitherTryCast $ \s ->
+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 TryCast.TryCast Natural.Natural Double where
-  tryCast = Utility.eitherTryCast $ \s -> if s <= maxDouble
+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 TryCast.TryCast Float Int.Int8 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Int.Int8 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Int.Int16 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Int.Int16 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Int.Int32 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Int.Int32 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Int.Int64 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Int.Int64 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Int where
-  tryCast = Utility.tryVia @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 TryCast.TryCast Float Integer where
-  tryCast = Utility.eitherTryCast $ \s -> case Utility.tryVia @Rational s of
+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
@@ -774,67 +771,67 @@
       | otherwise -> Right t
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Word.Word8 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Word.Word8 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Word.Word16 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Word.Word16 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Word.Word32 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Word.Word32 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Word.Word64 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Word.Word64 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Word where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Word where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Float Natural.Natural where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Float Natural.Natural where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Uses 'toRational' when the input is not NaN or infinity.
-instance TryCast.TryCast Float Rational where
-  tryCast = Utility.eitherTryCast $ \s -> if isNaN s
+instance TryFrom.TryFrom Float Rational where
+  tryFrom = Utility.eitherTryFrom $ \s -> if isNaN s
     then Left Exception.LossOfPrecision
     else if isInfinite s
       then if s > 0 then Left Exception.Overflow else Left Exception.Underflow
       else Right $ toRational s
 
 -- | Uses 'Float.float2Double'.
-instance Cast.Cast Float Double where
-  cast = Float.float2Double
+instance From.From Float Double where
+  from = Float.float2Double
 
 -- Double
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Int.Int8 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Int.Int8 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Int.Int16 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Int.Int16 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Int.Int32 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Int.Int32 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Int.Int64 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Int.Int64 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Int where
-  tryCast = Utility.tryVia @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 TryCast.TryCast Double Integer where
-  tryCast = Utility.eitherTryCast $ \s -> case Utility.tryVia @Rational s of
+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
@@ -842,269 +839,245 @@
       | otherwise -> Right t
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Word.Word8 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Word.Word8 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Word.Word16 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Word.Word16 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Word.Word32 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Word.Word32 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Word.Word64 where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Word.Word64 where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Word where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Word where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Converts via 'Integer'.
-instance TryCast.TryCast Double Natural.Natural where
-  tryCast = Utility.tryVia @Integer
+instance TryFrom.TryFrom Double Natural.Natural where
+  tryFrom = Utility.tryVia @Integer
 
 -- | Uses 'toRational' when the input is not NaN or infinity.
-instance TryCast.TryCast Double Rational where
-  tryCast = Utility.eitherTryCast $ \s -> if isNaN s
+instance TryFrom.TryFrom Double Rational where
+  tryFrom = Utility.eitherTryFrom $ \s -> if isNaN s
     then Left Exception.LossOfPrecision
     else if isInfinite s
       then if s > 0 then Left Exception.Overflow else Left Exception.Underflow
       else Right $ toRational s
 
 -- | Uses 'Float.double2Float'. This necessarily loses some precision.
-instance Cast.Cast Double Float where
-  cast = Float.double2Float
+instance From.From Double Float where
+  from = Float.double2Float
 
 -- Ratio
 
 -- | Uses '(Ratio.%)' with a denominator of 1.
-instance Integral a => Cast.Cast a (Ratio.Ratio a) where
-  cast = (Ratio.% 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) => TryCast.TryCast (Ratio.Ratio a) a where
-  tryCast = Utility.eitherTryCast $ \s -> if Ratio.denominator s == 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 Cast.Cast Rational Float where
-  cast = fromRational
+instance From.From Rational Float where
+  from = fromRational
 
 -- | Uses 'fromRational'. This necessarily loses some precision.
-instance Cast.Cast Rational Double where
-  cast = fromRational
+instance From.From Rational Double where
+  from = fromRational
 
 -- Fixed
 
--- | Uses 'Fixed.MkFixed'. This means @cast 2 :: Centi@ is @0.02@ rather than
--- @2.00@.
-instance Cast.Cast Integer (Fixed.Fixed a) where
-  cast = Fixed.MkFixed
+-- | 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 @cast (3.00 :: Centi)@ is @300@ rather
--- than @3@.
-instance Cast.Cast (Fixed.Fixed a) Integer where
-  cast (Fixed.MkFixed t) = t
+-- | 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
 
 -- Complex
 
 -- | Uses '(Complex.:+)' with an imaginary part of 0.
-instance Num a => Cast.Cast a (Complex.Complex a) where
-  cast = (Complex.:+ 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) => TryCast.TryCast (Complex.Complex a) a where
-  tryCast = Utility.eitherTryCast $ \s -> if Complex.imagPart s == 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 TryCast.TryCast [a] (NonEmpty.NonEmpty a) where
-  tryCast = Utility.maybeTryCast NonEmpty.nonEmpty
+instance TryFrom.TryFrom [a] (NonEmpty.NonEmpty a) where
+  tryFrom = Utility.maybeTryFrom NonEmpty.nonEmpty
 
 -- | Uses 'NonEmpty.toList'.
-instance Cast.Cast (NonEmpty.NonEmpty a) [a] where
-  cast = NonEmpty.toList
+instance From.From (NonEmpty.NonEmpty a) [a] where
+  from = NonEmpty.toList
 
 -- Set
 
 -- | Uses 'Set.fromList'.
-instance Ord a => Cast.Cast [a] (Set.Set a) where
-  cast = Set.fromList
+instance Ord a => From.From [a] (Set.Set a) where
+  from = Set.fromList
 
 -- | Uses 'Set.toAscList'.
-instance Cast.Cast (Set.Set a) [a] where
-  cast = Set.toAscList
+instance From.From (Set.Set a) [a] where
+  from = Set.toAscList
 
 -- IntSet
 
 -- | Uses 'IntSet.fromList'.
-instance Cast.Cast [Int] IntSet.IntSet where
-  cast = IntSet.fromList
+instance From.From [Int] IntSet.IntSet where
+  from = IntSet.fromList
 
 -- | Uses 'IntSet.toAscList'.
-instance Cast.Cast IntSet.IntSet [Int] where
-  cast = 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 => Cast.Cast [(k, v)] (Map.Map k v) where
-  cast = Map.fromList
+instance Ord k => From.From [(k, v)] (Map.Map k v) where
+  from = Map.fromList
 
 -- | Uses 'Map.toAscList'.
-instance Cast.Cast (Map.Map k v) [(k, v)] where
-  cast = 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 Cast.Cast [(Int, v)] (IntMap.IntMap v) where
-  cast = IntMap.fromList
+instance From.From [(Int, v)] (IntMap.IntMap v) where
+  from = IntMap.fromList
 
 -- | Uses 'IntMap.toAscList'.
-instance Cast.Cast (IntMap.IntMap v) [(Int, v)] where
-  cast = IntMap.toAscList
+instance From.From (IntMap.IntMap v) [(Int, v)] where
+  from = IntMap.toAscList
 
 -- Seq
 
 -- | Uses 'Seq.fromList'.
-instance Cast.Cast [a] (Seq.Seq a) where
-  cast = Seq.fromList
+instance From.From [a] (Seq.Seq a) where
+  from = Seq.fromList
 
 -- | Uses 'Foldable.toList'.
-instance Cast.Cast (Seq.Seq a) [a] where
-  cast = Foldable.toList
+instance From.From (Seq.Seq a) [a] where
+  from = Foldable.toList
 
 -- ByteString
 
 -- | Uses 'ByteString.pack'.
-instance Cast.Cast [Word.Word8] ByteString.ByteString where
-  cast = ByteString.pack
+instance From.From [Word.Word8] ByteString.ByteString where
+  from = ByteString.pack
 
 -- | Uses 'ByteString.unpack'.
-instance Cast.Cast ByteString.ByteString [Word.Word8] where
-  cast = ByteString.unpack
+instance From.From ByteString.ByteString [Word.Word8] where
+  from = ByteString.unpack
 
 -- | Uses 'LazyByteString.fromStrict'.
-instance Cast.Cast ByteString.ByteString LazyByteString.ByteString where
-  cast = LazyByteString.fromStrict
+instance From.From ByteString.ByteString LazyByteString.ByteString where
+  from = LazyByteString.fromStrict
 
 -- | Uses 'ShortByteString.toShort'.
-instance Cast.Cast ByteString.ByteString ShortByteString.ShortByteString where
-  cast = ShortByteString.toShort
+instance From.From ByteString.ByteString ShortByteString.ShortByteString where
+  from = ShortByteString.toShort
 
 -- | Uses 'Text.decodeUtf8''.
-instance TryCast.TryCast ByteString.ByteString Text.Text where
-  tryCast = Utility.eitherTryCast Text.decodeUtf8'
+instance TryFrom.TryFrom ByteString.ByteString Text.Text where
+  tryFrom = Utility.eitherTryFrom Text.decodeUtf8'
 
 -- LazyByteString
 
 -- | Uses 'LazyByteString.pack'.
-instance Cast.Cast [Word.Word8] LazyByteString.ByteString where
-  cast = LazyByteString.pack
+instance From.From [Word.Word8] LazyByteString.ByteString where
+  from = LazyByteString.pack
 
 -- | Uses 'LazyByteString.unpack'.
-instance Cast.Cast LazyByteString.ByteString [Word.Word8] where
-  cast = LazyByteString.unpack
+instance From.From LazyByteString.ByteString [Word.Word8] where
+  from = LazyByteString.unpack
 
 -- | Uses 'LazyByteString.toStrict'.
-instance Cast.Cast LazyByteString.ByteString ByteString.ByteString where
-  cast = LazyByteString.toStrict
+instance From.From LazyByteString.ByteString ByteString.ByteString where
+  from = LazyByteString.toStrict
 
 -- | Uses 'LazyText.decodeUtf8''.
-instance TryCast.TryCast LazyByteString.ByteString LazyText.Text where
-  tryCast = Utility.eitherTryCast LazyText.decodeUtf8'
+instance TryFrom.TryFrom LazyByteString.ByteString LazyText.Text where
+  tryFrom = Utility.eitherTryFrom LazyText.decodeUtf8'
 
 -- ShortByteString
 
 -- | Uses 'ShortByteString.pack'.
-instance Cast.Cast [Word.Word8] ShortByteString.ShortByteString where
-  cast = ShortByteString.pack
+instance From.From [Word.Word8] ShortByteString.ShortByteString where
+  from = ShortByteString.pack
 
 -- | Uses 'ShortByteString.unpack'.
-instance Cast.Cast ShortByteString.ShortByteString [Word.Word8] where
-  cast = ShortByteString.unpack
+instance From.From ShortByteString.ShortByteString [Word.Word8] where
+  from = ShortByteString.unpack
 
 -- | Uses 'ShortByteString.fromShort'.
-instance Cast.Cast ShortByteString.ShortByteString ByteString.ByteString where
-  cast = ShortByteString.fromShort
+instance From.From ShortByteString.ShortByteString ByteString.ByteString where
+  from = ShortByteString.fromShort
 
 -- Text
 
 -- | Uses 'Text.pack'. Some 'Char' values cannot be represented in 'Text.Text'
 -- and will be replaced with @'\\xFFFD'@.
-instance Cast.Cast String Text.Text where
-  cast = Text.pack
+instance From.From String Text.Text where
+  from = Text.pack
 
 -- | Uses 'Text.unpack'.
-instance Cast.Cast Text.Text String where
-  cast = Text.unpack
+instance From.From Text.Text String where
+  from = Text.unpack
 
 -- | Uses 'LazyText.fromStrict'.
-instance Cast.Cast Text.Text LazyText.Text where
-  cast = LazyText.fromStrict
+instance From.From Text.Text LazyText.Text where
+  from = LazyText.fromStrict
 
 -- | Uses 'Text.encodeUtf8'.
-instance Cast.Cast Text.Text ByteString.ByteString where
-  cast = Text.encodeUtf8
+instance From.From Text.Text ByteString.ByteString where
+  from = Text.encodeUtf8
 
 -- LazyText
 
 -- | Uses 'LazyText.pack'. Some 'Char' values cannot be represented in
 -- 'LazyText.Text' and will be replaced with @'\\xFFFD'@.
-instance Cast.Cast String LazyText.Text where
-  cast = LazyText.pack
+instance From.From String LazyText.Text where
+  from = LazyText.pack
 
 -- | Uses 'LazyText.unpack'.
-instance Cast.Cast LazyText.Text String where
-  cast = LazyText.unpack
+instance From.From LazyText.Text String where
+  from = LazyText.unpack
 
 -- | Uses 'LazyText.toStrict'.
-instance Cast.Cast LazyText.Text Text.Text where
-  cast = LazyText.toStrict
+instance From.From LazyText.Text Text.Text where
+  from = LazyText.toStrict
 
 -- | Uses 'LazyText.encodeUtf8'.
-instance Cast.Cast LazyText.Text LazyByteString.ByteString where
-  cast = LazyText.encodeUtf8
+instance From.From LazyText.Text LazyByteString.ByteString where
+  from = LazyText.encodeUtf8
 
--- TryCastException
+-- TryFromException
 
 -- | Uses @coerce@.
-instance Cast.Cast
-  (TryCastException.TryCastException s u)
-  (TryCastException.TryCastException s t)
-
--- | Uses 'show'.
-instance
-  ( Show s
-  , Typeable.Typeable s
-  , Typeable.Typeable t
-  ) => Cast.Cast (TryCastException.TryCastException s t) String where
-  cast = show
-
--- | Converts via 'String'.
-instance
-  ( Show s
-  , Typeable.Typeable s
-  , Typeable.Typeable t
-  ) => Cast.Cast (TryCastException.TryCastException s t) Text.Text where
-  cast = Utility.via @String
-
--- | Converts via 'String'.
-instance
-  ( Show s
-  , Typeable.Typeable s
-  , Typeable.Typeable t
-  ) => Cast.Cast (TryCastException.TryCastException s t) LazyText.Text where
-  cast = Utility.via @String
+instance From.From
+  (TryFromException.TryFromException s u)
+  (TryFromException.TryFromException s t)
 
 fromNonNegativeIntegral
   :: (Integral s, Num t) => s -> Either Exception.ArithException t
diff --git a/src/lib/Witch/TryCast.hs b/src/lib/Witch/TryCast.hs
deleted file mode 100644
--- a/src/lib/Witch/TryCast.hs
+++ /dev/null
@@ -1,21 +0,0 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module Witch.TryCast where
-
-import qualified Witch.TryCastException as TryCastException
-
--- | This type class is for converting values from some @source@ type into
--- some other @target@ type. The constraint @TryCast 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 fail. If your conversion cannot
--- fail, consider implementing @Cast@ instead.
-class TryCast source target where
-  -- | This method implements the conversion of a value between types. At call
-  -- sites you will usually want to use @tryFrom@ or @tryInto@ instead of this
-  -- method.
-  --
-  -- Consider using @maybeTryCast@ or @eitherTryCast@ to implement this
-  -- method.
-  tryCast :: source -> Either (TryCastException.TryCastException source target) target
diff --git a/src/lib/Witch/TryCastException.hs b/src/lib/Witch/TryCastException.hs
deleted file mode 100644
--- a/src/lib/Witch/TryCastException.hs
+++ /dev/null
@@ -1,38 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Witch.TryCastException 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 @TryCast@ 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 TryCastException source target = TryCastException
-  source
-  (Maybe Exception.SomeException)
-
-instance
-  ( Show source
-  , Typeable.Typeable source
-  , Typeable.Typeable target
-  ) => Show (TryCastException source target) where
-  showsPrec d (TryCastException x e) =
-    showParen (d > 10)
-      $ showString "TryCastException @"
-      . 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 (TryCastException source target)
diff --git a/src/lib/Witch/TryFrom.hs b/src/lib/Witch/TryFrom.hs
new file mode 100644
--- /dev/null
+++ b/src/lib/Witch/TryFrom.hs
@@ -0,0 +1,20 @@
+{-# 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 fail. If your conversion cannot
+-- fail, consider implementing @From@ instead.
+class TryFrom source target where
+  -- | This method implements the conversion of a value between types. At call
+  -- sites you will usually want to use @tryInto@ instead of this method.
+  --
+  -- 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
new file mode 100644
--- /dev/null
+++ b/src/lib/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/src/lib/Witch/Utility.hs b/src/lib/Witch/Utility.hs
--- a/src/lib/Witch/Utility.hs
+++ b/src/lib/Witch/Utility.hs
@@ -1,58 +1,40 @@
 {-# LANGUAGE AllowAmbiguousTypes #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
 
 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.Cast as Cast
-import qualified Witch.Identity as Identity
-import qualified Witch.TryCast as TryCast
-import qualified Witch.TryCastException as TryCastException
+import qualified Witch.From as From
+import qualified Witch.TryFrom as TryFrom
+import qualified Witch.TryFromException as TryFromException
 
--- | This is the same as 'id' except that it requires a type application. This
--- can be an ergonomic way to pin down a polymorphic type in a function
--- pipeline. For example:
+-- | 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 s source . Identity.Identity s ~ source => source -> source
+as :: forall source . source -> source
 as = id
 
--- | This is the same as 'Cast.cast' except that it requires a type
--- application for the @source@ type.
---
--- > -- Avoid this:
--- > cast (x :: s)
--- >
--- > -- Prefer this:
--- > from @s x
-from
-  :: forall s target source
-   . (Identity.Identity s ~ source, Cast.Cast source target)
-  => source
-  -> target
-from = Cast.cast
-
--- | This is the same as 'Cast.cast' except that it requires a type
--- application for the @target@ type.
+-- | This is the same as 'From.from' except that the type variables are in the
+-- opposite order.
 --
 -- > -- Avoid this:
--- > cast x :: t
+-- > from x :: t
 -- >
 -- > -- Prefer this:
 -- > into @t x
 into
-  :: forall t source target
-   . (Identity.Identity t ~ target, Cast.Cast source target)
+  :: forall target source
+   . From.From source target
   => source
   -> target
-into = Cast.cast
+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
@@ -65,19 +47,18 @@
 -- > -- Prefer this:
 -- > over @t f
 over
-  :: forall t source target
-   . ( Identity.Identity t ~ target
-     , Cast.Cast source target
-     , Cast.Cast target source
+  :: forall target source
+   . ( From.From source target
+     , From.From target source
      )
   => (target -> target)
   -> source
   -> source
-over f = Cast.cast . f . Cast.cast
+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 'Cast.Cast' instances. Sometimes this can be used to work
+-- when writing 'From.From' instances. Sometimes this can be used to work
 -- around the lack of an instance that should probably exist.
 --
 -- > -- Avoid this:
@@ -86,170 +67,131 @@
 -- > -- Prefer this:
 -- > via @u
 via
-  :: forall u source target through
-   . ( Identity.Identity u ~ through
-     , Cast.Cast source through
-     , Cast.Cast through target
+  :: forall through source target
+   . ( From.From source through
+     , From.From through target
      )
   => source
   -> target
-via = Cast.cast . (\x -> x :: through) . Cast.cast
-
--- | This is the same as 'TryCast.tryCast' except that it requires a type
--- application for the @source@ type.
---
--- > -- Avoid this:
--- > tryCast (x :: s)
--- >
--- > -- Prefer this:
--- > tryFrom @s x
-tryFrom
-  :: forall s target source
-   . (Identity.Identity s ~ source, TryCast.TryCast source target)
-  => source
-  -> Either (TryCastException.TryCastException source target) target
-tryFrom = TryCast.tryCast
+via = From.from . (\x -> x :: through) . From.from
 
--- | This is the same as 'TryCast.tryCast' except that it requires a type
--- application for the @target@ type.
+-- | This is the same as 'TryFrom.tryFrom' except that the type variables are
+-- in the opposite order.
 --
 -- > -- Avoid this:
--- > tryCast x :: Either (TryCastException s t) t
+-- > tryFrom x :: Either (TryFromException s t) t
 -- >
 -- > -- Prefer this:
 -- > tryInto @t x
 tryInto
-  :: forall t source target
-   . (Identity.Identity t ~ target, TryCast.TryCast source target)
+  :: forall target source
+   . TryFrom.TryFrom source target
   => source
-  -> Either (TryCastException.TryCastException source target) target
-tryInto = TryCast.tryCast
+  -> Either (TryFromException.TryFromException source target) target
+tryInto = TryFrom.tryFrom
 
--- | This is similar to 'via' except that it works with 'TryCast.TryCast'
+-- | 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 'TryCastException.TryCastException' can be tedious.
+-- the types in the 'TryFromException.TryFromException' can be tedious.
 --
 -- > -- Avoid this:
 -- > case tryInto @u x of
 -- >   Left _ -> Left ...
 -- >   Right y -> case tryFrom @u y of
 -- >     Left _ -> Left ...
--- >     Right z -> ...
+-- >     Right z -> Right z
 -- >
 -- > -- Prefer this:
 -- > tryVia @u
 tryVia
-  :: forall u source target through
-   . ( Identity.Identity u ~ through
-     , TryCast.TryCast source through
-     , TryCast.TryCast through target
+  :: forall through source target
+   . ( TryFrom.TryFrom source through
+     , TryFrom.TryFrom through target
      )
   => source
-  -> Either (TryCastException.TryCastException source target) target
-tryVia s = case TryCast.tryCast s of
-  Left (TryCastException.TryCastException _ e) ->
-    Left $ TryCastException.TryCastException s e
-  Right u -> case TryCast.tryCast (u :: through) of
-    Left (TryCastException.TryCastException _ e) ->
-      Left $ TryCastException.TryCastException s e
+  -> 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 'TryCast.tryCast' with a function
+-- | This function can be used to implement 'TryFrom.tryFrom' with a function
 -- that returns 'Maybe'. For example:
 --
 -- > -- Avoid this:
--- > tryCast s = case f s of
--- >   Nothing -> Left $ TryCastException s Nothing
+-- > tryFrom s = case f s of
+-- >   Nothing -> Left $ TryFromException s Nothing
 -- >   Just t -> Right t
 -- >
 -- > -- Prefer this:
--- > tryCast = maybeTryCast f
-maybeTryCast
+-- > tryFrom = maybeTryFrom f
+maybeTryFrom
   :: (source -> Maybe target)
   -> source
-  -> Either (TryCastException.TryCastException source target) target
-maybeTryCast f s = case f s of
-  Nothing -> Left $ TryCastException.TryCastException s Nothing
+  -> 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 'TryCast.tryCast' with a function
+-- | This function can be used to implement 'TryFrom.tryFrom' with a function
 -- that returns 'Either'. For example:
 --
 -- > -- Avoid this:
--- > tryCast s = case f s of
--- >   Left e -> Left . TryCastException s . Just $ toException e
+-- > tryFrom s = case f s of
+-- >   Left e -> Left . TryFromException s . Just $ toException e
 -- >   Right t -> Right t
 -- >
 -- > -- Prefer this:
--- > tryCast = eitherTryCast f
-eitherTryCast
+-- > tryFrom = eitherTryFrom f
+eitherTryFrom
   :: Exception.Exception exception
   => (source -> Either exception target)
   -> source
-  -> Either (TryCastException.TryCastException source target) target
-eitherTryCast f s = case f s of
+  -> Either (TryFromException.TryFromException source target) target
+eitherTryFrom f s = case f s of
   Left e ->
-    Left . TryCastException.TryCastException s . Just $ Exception.toException e
+    Left . TryFromException.TryFromException s . Just $ Exception.toException e
   Right t -> Right t
 
--- | This function is like 'TryCast.tryCast' except that it will throw an
+-- | This function is like 'TryFrom.tryFrom' except that it will throw an
 -- impure exception if the conversion fails.
 --
 -- > -- Avoid this:
--- > either throw id . cast
--- >
--- > -- Prefer this:
--- > unsafeCast
-unsafeCast
-  :: forall source target
-   . ( Stack.HasCallStack
-     , TryCast.TryCast source target
-     , Show source
-     , Typeable.Typeable source
-     , Typeable.Typeable target
-     )
-  => source
-  -> target
-unsafeCast = either Exception.throw id . TryCast.tryCast
-
--- | This function is like 'from' except that it will throw an impure
--- exception if the conversion fails.
---
--- > -- Avoid this:
--- > either throw id . from @s
+-- > either throw id . tryFrom @s
 -- >
 -- > -- Prefer this:
 -- > unsafeFrom @s
 unsafeFrom
-  :: forall s target source
-   . ( Identity.Identity s ~ source
-     , Stack.HasCallStack
-     , TryCast.TryCast source target
+  :: forall source target
+   . ( Stack.HasCallStack
+     , TryFrom.TryFrom source target
      , Show source
      , Typeable.Typeable source
      , Typeable.Typeable target
      )
   => source
   -> target
-unsafeFrom = unsafeCast
+unsafeFrom = either Exception.throw id . TryFrom.tryFrom
 
--- | This function is like 'into' except that it will throw an impure
+-- | This function is like 'tryInto' except that it will throw an impure
 -- exception if the conversion fails.
 --
 -- > -- Avoid this:
--- > either throw id . into @t
+-- > either throw id . tryInto @t
 -- >
 -- > -- Prefer this:
 -- > unsafeInto @t
 unsafeInto
-  :: forall t source target
-   . ( Identity.Identity t ~ target
-     , Stack.HasCallStack
-     , TryCast.TryCast source target
+  :: forall target source
+   . ( Stack.HasCallStack
+     , TryFrom.TryFrom source target
      , Show source
      , Typeable.Typeable source
      , Typeable.Typeable target
      )
   => source
   -> target
-unsafeInto = unsafeCast
+unsafeInto = unsafeFrom
diff --git a/src/test/Main.hs b/src/test/Main.hs
--- a/src/test/Main.hs
+++ b/src/test/Main.hs
@@ -1,1723 +1,1665 @@
-{-# LANGUAGE DerivingVia #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE TypeApplications #-}
-
-import qualified Control.Exception as Exception
-import qualified Control.Monad as Monad
-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.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.Word as Word
-import qualified Numeric.Natural as Natural
-import qualified Test.Hspec as Hspec
-import qualified Test.Hspec.QuickCheck as Hspec
-import Test.QuickCheck ((===))
-import qualified Text.Read as Read
-import qualified Witch
-
-main :: IO ()
-main = Hspec.hspec . Hspec.describe "Witch" $ do
-
-  Hspec.describe "Cast" $ do
-
-    Hspec.describe "cast" $ do
-      test $ Witch.cast (1 :: Int.Int8) `Hspec.shouldBe` (1 :: Int.Int16)
-
-  Hspec.describe "TryCast" $ do
-
-    Hspec.describe "tryCast" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Int.Int8
-      test $ f 1 `Hspec.shouldBe` Just 1
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-  Hspec.describe "Utility" $ do
-
-    Hspec.describe "as" $ do
-      test $ Witch.as @Int.Int8 1 `Hspec.shouldBe` 1
-
-    Hspec.describe "from" $ do
-      test $ Witch.from @Int.Int8 1 `Hspec.shouldBe` (1 :: Int.Int16)
-
-    Hspec.describe "into" $ do
-      test $ Witch.into @Int.Int16 (1 :: Int.Int8) `Hspec.shouldBe` 1
-
-    Hspec.describe "over" $ do
-      test $ Witch.over @Int.Int8 (+ 1) (Age 1) `Hspec.shouldBe` Age 2
-
-    Hspec.describe "via" $ do
-      test $ Witch.via @Int.Int16 (1 :: Int.Int8) `Hspec.shouldBe` (1 :: Int.Int32)
-
-    Hspec.describe "tryFrom" $ do
-      test $ hush (Witch.tryFrom @Int.Int16 1) `Hspec.shouldBe` Just (1 :: Int.Int8)
-
-    Hspec.describe "tryInto" $ do
-      test $ hush (Witch.tryInto @Int.Int8 (1 :: Int.Int16)) `Hspec.shouldBe` Just 1
-
-    Hspec.describe "unsafeCast" $ do
-      test $ Witch.unsafeCast (1 :: Int.Int16) `Hspec.shouldBe` (1 :: Int.Int8)
-      test $ Exception.evaluate (Witch.unsafeCast @Int.Int16 @Int.Int8 128) `Hspec.shouldThrow` Hspec.anyException
-
-    Hspec.describe "unsafeFrom" $ do
-      test $ Witch.unsafeFrom @Int.Int16 1 `Hspec.shouldBe` (1 :: Int.Int8)
-
-    Hspec.describe "unsafeInto" $ do
-      test $ Witch.unsafeInto @Int.Int8 (1 :: Int.Int16) `Hspec.shouldBe` 1
-
-  Hspec.describe "Lift" $ do
-
-    Hspec.describe "liftedCast" $ do
-      test $ ($$(Witch.liftedCast (1 :: Int.Int16)) :: Int.Int8) `Hspec.shouldBe` 1
-
-    Hspec.describe "liftedFrom" $ do
-      test $ ($$(Witch.liftedFrom @Int.Int16 1) :: Int.Int8) `Hspec.shouldBe` 1
-
-    Hspec.describe "liftedInto" $ do
-      test $ $$(Witch.liftedInto @Int.Int8 (1 :: Int.Int16)) `Hspec.shouldBe` 1
-
-  Hspec.describe "Instances" $ do
-
-    -- Int8
-
-    Hspec.describe "Cast Int8 Int16" $ do
-      let f = Witch.cast @Int.Int8 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    Hspec.describe "Cast Int8 Int32" $ do
-      let f = Witch.cast @Int.Int8 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    Hspec.describe "Cast Int8 Int64" $ do
-      let f = Witch.cast @Int.Int8 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    Hspec.describe "Cast Int8 Int" $ do
-      let f = Witch.cast @Int.Int8 @Int
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    Hspec.describe "Cast Int8 Integer" $ do
-      let f = Witch.cast @Int.Int8 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    Hspec.describe "TryCast Int8 Word8" $ do
-      let f = hush . Witch.tryCast @Int.Int8 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int8 Word16" $ do
-      let f = hush . Witch.tryCast @Int.Int8 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int8 Word32" $ do
-      let f = hush . Witch.tryCast @Int.Int8 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int8 Word64" $ do
-      let f = hush . Witch.tryCast @Int.Int8 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int8 Word" $ do
-      let f = hush . Witch.tryCast @Int.Int8 @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int8 Natural" $ do
-      let f = hush . Witch.tryCast @Int.Int8 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Int8 Float" $ do
-      let f = Witch.cast @Int.Int8 @Float
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    Hspec.describe "Cast Int8 Double" $ do
-      let f = Witch.cast @Int.Int8 @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 127 `Hspec.shouldBe` 127
-      test $ f (-128) `Hspec.shouldBe` (-128)
-
-    -- Int16
-
-    Hspec.describe "TryCast Int16 Int8" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Int16 Int32" $ do
-      let f = Witch.cast @Int.Int16 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 32767 `Hspec.shouldBe` 32767
-      test $ f (-32768) `Hspec.shouldBe` (-32768)
-
-    Hspec.describe "Cast Int16 Int64" $ do
-      let f = Witch.cast @Int.Int16 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 32767 `Hspec.shouldBe` 32767
-      test $ f (-32768) `Hspec.shouldBe` (-32768)
-
-    Hspec.describe "Cast Int16 Int" $ do
-      let f = Witch.cast @Int.Int16 @Int
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 32767 `Hspec.shouldBe` 32767
-      test $ f (-32768) `Hspec.shouldBe` (-32768)
-
-    Hspec.describe "Cast Int16 Integer" $ do
-      let f = Witch.cast @Int.Int16 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 32767 `Hspec.shouldBe` 32767
-      test $ f (-32768) `Hspec.shouldBe` (-32768)
-
-    Hspec.describe "TryCast Int16 Word8" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int16 Word16" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int16 Word32" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int16 Word64" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int16 Word" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int16 Natural" $ do
-      let f = hush . Witch.tryCast @Int.Int16 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Int16 Float" $ do
-      let f = Witch.cast @Int.Int16 @Float
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 32767 `Hspec.shouldBe` 32767
-      test $ f (-32768) `Hspec.shouldBe` (-32768)
-
-    Hspec.describe "Cast Int16 Double" $ do
-      let f = Witch.cast @Int.Int16 @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 32767 `Hspec.shouldBe` 32767
-      test $ f (-32768) `Hspec.shouldBe` (-32768)
-
-    -- Int32
-
-    Hspec.describe "TryCast Int32 Int8" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Int16" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
-      test $ f (-32769) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Int32 Int64" $ do
-      let f = Witch.cast @Int.Int32 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 2147483647 `Hspec.shouldBe` 2147483647
-      test $ f (-2147483648) `Hspec.shouldBe` (-2147483648)
-
-    Hspec.describe "TryCast Int32 Int" $ do
-      Monad.when (toInteger (maxBound :: Int) < 2147483647) untested
-      let f = hush . Witch.tryCast @Int.Int32 @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
-
-    Hspec.describe "Cast Int32 Integer" $ do
-      let f = Witch.cast @Int.Int32 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 2147483647 `Hspec.shouldBe` 2147483647
-      test $ f (-2147483648) `Hspec.shouldBe` (-2147483648)
-
-    Hspec.describe "TryCast Int32 Word8" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Word16" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Word32" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Word64" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Word" $ do
-      Monad.when (toInteger (maxBound :: Word) < 2147483647) untested
-      let f = hush . Witch.tryCast @Int.Int32 @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Natural" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int32 Float" $ do
-      let f = hush . Witch.tryCast @Int.Int32 @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Int32 Double" $ do
-      let f = Witch.cast @Int.Int32 @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 2147483647 `Hspec.shouldBe` 2147483647
-      test $ f (-2147483648) `Hspec.shouldBe` (-2147483648)
-
-    -- Int64
-
-    Hspec.describe "TryCast Int64 Int8" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Int16" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
-      test $ f (-32769) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Int32" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
-      test $ f (-2147483649) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Int" $ do
-      Monad.when (toInteger (maxBound :: Int) < 9223372036854775807) untested
-      let f = hush . Witch.tryCast @Int.Int64 @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f (-9223372036854775808) `Hspec.shouldBe` Just (-9223372036854775808)
-
-    Hspec.describe "Cast Int64 Integer" $ do
-      let f = Witch.cast @Int.Int64 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` 9223372036854775807
-      test $ f (-9223372036854775808) `Hspec.shouldBe` (-9223372036854775808)
-
-    Hspec.describe "TryCast Int64 Word8" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Word16" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Word32" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Word64" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Word" $ do
-      Monad.when (toInteger (maxBound :: Word) < 9223372036854775807) untested
-      let f = hush . Witch.tryCast @Int.Int64 @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Natural" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Float" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int64 Double" $ do
-      let f = hush . Witch.tryCast @Int.Int64 @Double
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
-
-    -- Int
-
-    Hspec.describe "TryCast Int Int8" $ do
-      let f = hush . Witch.tryCast @Int @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Int16" $ do
-      let f = hush . Witch.tryCast @Int @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
-      test $ f (-32769) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Int32" $ do
-      Monad.when (toInteger (maxBound :: Int) < 2147483647) untested
-      let f = hush . Witch.tryCast @Int @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
-      test $ f (-2147483649) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Int Int64" $ do
-      let f = Witch.cast @Int @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Int)
-      test $ f minBound `Hspec.shouldBe` fromIntegral (minBound :: Int)
-
-    Hspec.describe "Cast Int Integer" $ do
-      let f = Witch.cast @Int @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Int)
-      test $ f minBound `Hspec.shouldBe` fromIntegral (minBound :: Int)
-
-    Hspec.describe "TryCast Int Word8" $ do
-      let f = hush . Witch.tryCast @Int @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Word16" $ do
-      let f = hush . Witch.tryCast @Int @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Word32" $ do
-      Monad.when (toInteger (maxBound :: Int) < 4294967295) untested
-      let f = hush . Witch.tryCast @Int @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-      test $ f 4294967296 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Word64" $ do
-      let f = hush . Witch.tryCast @Int @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f maxBound `Hspec.shouldBe` Just (fromIntegral (maxBound :: Int))
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Word" $ do
-      let f = hush . Witch.tryCast @Int @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f maxBound `Hspec.shouldBe` Just (fromIntegral (maxBound :: Int))
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Natural" $ do
-      let f = hush . Witch.tryCast @Int @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f maxBound `Hspec.shouldBe` Just (fromIntegral (maxBound :: Int))
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Float" $ do
-      let f = hush . Witch.tryCast @Int @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Int Double" $ do
-      Monad.when (toInteger (maxBound :: Int) < 9007199254740991) untested
-      let f = hush . Witch.tryCast @Int @Double
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
-
-    -- Integer
-
-    Hspec.describe "TryCast Integer Int8" $ do
-      let f = hush . Witch.tryCast @Integer @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Int16" $ do
-      let f = hush . Witch.tryCast @Integer @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
-      test $ f (-32769) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Int32" $ do
-      let f = hush . Witch.tryCast @Integer @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
-      test $ f (-2147483649) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Int64" $ do
-      let f = hush . Witch.tryCast @Integer @Int.Int64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
-      test $ f (-9223372036854775808) `Hspec.shouldBe` Just (-9223372036854775808)
-      test $ f (-9223372036854775809) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Int" $ do
-      let f = hush . Witch.tryCast @Integer @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ let x = maxBound :: Int in f (fromIntegral x) `Hspec.shouldBe` Just x
-      test $ let x = toInteger (maxBound :: Int) + 1 in f x `Hspec.shouldBe` Nothing
-      test $ let x = minBound :: Int in f (fromIntegral x) `Hspec.shouldBe` Just x
-      test $ let x = toInteger (minBound :: Int) - 1 in f x `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Word8" $ do
-      let f = hush . Witch.tryCast @Integer @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Word16" $ do
-      let f = hush . Witch.tryCast @Integer @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Word32" $ do
-      let f = hush . Witch.tryCast @Integer @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-      test $ f 4294967296 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Word64" $ do
-      let f = hush . Witch.tryCast @Integer @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 18446744073709551615 `Hspec.shouldBe` Just 18446744073709551615
-      test $ f 18446744073709551616 `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Word" $ do
-      let f = hush . Witch.tryCast @Integer @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ let x = maxBound :: Word in f (fromIntegral x) `Hspec.shouldBe` Just x
-      test $ let x = toInteger (maxBound :: Word) + 1 in f x `Hspec.shouldBe` Nothing
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Natural" $ do
-      let f = hush . Witch.tryCast @Integer @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 18446744073709551616 `Hspec.shouldBe` Just 18446744073709551616
-      test $ f (-1) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Float" $ do
-      let f = hush . Witch.tryCast @Integer @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Integer Double" $ do
-      let f = hush . Witch.tryCast @Integer @Double
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
-
-    -- Word8
-
-    Hspec.describe "Cast Word8 Word16" $ do
-      let f = Witch.cast @Word.Word8 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Word32" $ do
-      let f = Witch.cast @Word.Word8 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Word64" $ do
-      let f = Witch.cast @Word.Word8 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Word" $ do
-      let f = Witch.cast @Word.Word8 @Word
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Natural" $ do
-      let f = Witch.cast @Word.Word8 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "TryCast Word8 Int8" $ do
-      let f = hush . Witch.tryCast @Word.Word8 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word8 Int16" $ do
-      let f = Witch.cast @Word.Word8 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Int32" $ do
-      let f = Witch.cast @Word.Word8 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Int64" $ do
-      let f = Witch.cast @Word.Word8 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Int" $ do
-      let f = Witch.cast @Word.Word8 @Int
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Integer" $ do
-      let f = Witch.cast @Word.Word8 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Float" $ do
-      let f = Witch.cast @Word.Word8 @Float
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    Hspec.describe "Cast Word8 Double" $ do
-      let f = Witch.cast @Word.Word8 @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 255 `Hspec.shouldBe` 255
-
-    -- Word16
-
-    Hspec.describe "TryCast Word16 Word8" $ do
-      let f = hush . Witch.tryCast @Word.Word16 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word16 Word32" $ do
-      let f = Witch.cast @Word.Word16 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Word64" $ do
-      let f = Witch.cast @Word.Word16 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Word" $ do
-      let f = Witch.cast @Word.Word16 @Word
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Natural" $ do
-      let f = Witch.cast @Word.Word16 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "TryCast Word16 Int8" $ do
-      let f = hush . Witch.tryCast @Word.Word16 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word16 Int16" $ do
-      let f = hush . Witch.tryCast @Word.Word16 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word16 Int32" $ do
-      let f = Witch.cast @Word.Word16 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Int64" $ do
-      let f = Witch.cast @Word.Word16 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Int" $ do
-      let f = Witch.cast @Word.Word16 @Int
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Integer" $ do
-      let f = Witch.cast @Word.Word16 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Float" $ do
-      let f = Witch.cast @Word.Word16 @Float
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    Hspec.describe "Cast Word16 Double" $ do
-      let f = Witch.cast @Word.Word16 @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 65535 `Hspec.shouldBe` 65535
-
-    -- Word32
-
-    Hspec.describe "TryCast Word32 Word8" $ do
-      let f = hush . Witch.tryCast @Word.Word32 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word32 Word16" $ do
-      let f = hush . Witch.tryCast @Word.Word32 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word32 Word64" $ do
-      let f = Witch.cast @Word.Word32 @Word.Word64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 4294967295 `Hspec.shouldBe` 4294967295
-
-    Hspec.describe "TryCast Word32 Word" $ do
-      Monad.when (toInteger (maxBound :: Word) < 4294967295) untested
-      let f = hush . Witch.tryCast @Word.Word32 @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-
-    Hspec.describe "Cast Word32 Natural" $ do
-      let f = Witch.cast @Word.Word32 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 4294967295 `Hspec.shouldBe` 4294967295
-
-    Hspec.describe "TryCast Word32 Int8" $ do
-      let f = hush . Witch.tryCast @Word.Word32 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word32 Int16" $ do
-      let f = hush . Witch.tryCast @Word.Word32 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word32 Int32" $ do
-      let f = hush . Witch.tryCast @Word.Word32 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word32 Int64" $ do
-      let f = Witch.cast @Word.Word32 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 4294967295 `Hspec.shouldBe` 4294967295
-
-    Hspec.describe "TryCast Word32 Int" $ do
-      Monad.when (toInteger (maxBound :: Int) < 4294967295) untested
-      let f = hush . Witch.tryCast @Word.Word32 @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-
-    Hspec.describe "Cast Word32 Integer" $ do
-      let f = Witch.cast @Word.Word32 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 4294967295 `Hspec.shouldBe` 4294967295
-
-    Hspec.describe "TryCast Word32 Float" $ do
-      let f = hush . Witch.tryCast @Word.Word32 @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word32 Double" $ do
-      let f = Witch.cast @Word.Word32 @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 4294967295 `Hspec.shouldBe` 4294967295
-
-    -- Word64
-
-    Hspec.describe "TryCast Word64 Word8" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Word16" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Word32" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-      test $ f 4294967296 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Word" $ do
-      Monad.when (toInteger (maxBound :: Word) < 18446744073709551615) untested
-      let f = hush . Witch.tryCast @Word.Word64 @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 18446744073709551615 `Hspec.shouldBe` Just 18446744073709551615
-
-    Hspec.describe "Cast Word64 Natural" $ do
-      let f = Witch.cast @Word.Word64 @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 18446744073709551615 `Hspec.shouldBe` 18446744073709551615
-
-    Hspec.describe "TryCast Word64 Int8" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Int16" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Int32" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Int64" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Int.Int64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Int" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ let x = maxBound :: Int in hush (Witch.tryCast @Word.Word64 @Int (fromIntegral x)) `Hspec.shouldBe` Just x
-      test $ let x = fromIntegral (maxBound :: Int) + 1 :: Word.Word64 in hush (Witch.tryCast @Word.Word64 @Int x) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word64 Integer" $ do
-      let f = Witch.cast @Word.Word64 @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 18446744073709551615 `Hspec.shouldBe` 18446744073709551615
-
-    Hspec.describe "TryCast Word64 Float" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word64 Double" $ do
-      let f = hush . Witch.tryCast @Word.Word64 @Double
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-
-    -- Word
-
-    Hspec.describe "TryCast Word Word8" $ do
-      let f = hush . Witch.tryCast @Word @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Word16" $ do
-      let f = hush . Witch.tryCast @Word @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Word32" $ do
-      Monad.when (toInteger (maxBound :: Word) < 4294967295) untested
-      let f = hush . Witch.tryCast @Word @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-      test $ f 4294967296 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word Word64" $ do
-      let f = Witch.cast @Word @Word.Word64
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Word)
-
-    Hspec.describe "Cast Word Natural" $ do
-      let f = Witch.cast @Word @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Word)
-
-    Hspec.describe "TryCast Word Int8" $ do
-      let f = hush . Witch.tryCast @Word @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Int16" $ do
-      let f = hush . Witch.tryCast @Word @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Int32" $ do
-      Monad.when (toInteger (maxBound :: Word) < 2147483647) untested
-      let f = hush . Witch.tryCast @Word @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Int64" $ do
-      Monad.when (toInteger (maxBound :: Word) < 9223372036854775807) untested
-      let f = hush . Witch.tryCast @Word @Int.Int64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Int" $ do
-      let f = hush . Witch.tryCast @Word @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ let x = maxBound :: Int in hush (Witch.tryCast @Word @Int (fromIntegral x)) `Hspec.shouldBe` Just x
-      test $ let x = fromIntegral (maxBound :: Int) + 1 :: Word in hush (Witch.tryCast @Word @Int x) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Word Integer" $ do
-      let f = Witch.cast @Word @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Word)
-
-    Hspec.describe "TryCast Word Float" $ do
-      let f = hush . Witch.tryCast @Word @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Word Double" $ do
-      Monad.when (toInteger (maxBound :: Word) < 9007199254740991) untested
-      let f = hush . Witch.tryCast @Word @Double
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-
-    -- Natural
-
-    Hspec.describe "TryCast Natural Word8" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Word16" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Word32" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-      test $ f 4294967296 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Word64" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 18446744073709551615 `Hspec.shouldBe` Just 18446744073709551615
-      test $ f 18446744073709551616 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Word" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ let x = maxBound :: Word in hush (Witch.tryCast @Natural.Natural @Word (fromIntegral x)) `Hspec.shouldBe` Just x
-      test $ let x = fromIntegral (maxBound :: Word) + 1 :: Natural.Natural in hush (Witch.tryCast @Natural.Natural @Word x) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Int8" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Int16" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Int32" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Int64" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Int.Int64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
-      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Int" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ let x = maxBound :: Int in hush (Witch.tryCast @Natural.Natural @Int (fromIntegral x)) `Hspec.shouldBe` Just x
-      test $ let x = fromIntegral (maxBound :: Int) + 1 :: Natural.Natural in hush (Witch.tryCast @Natural.Natural @Int x) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Natural Integer" $ do
-      let f = Witch.cast @Natural.Natural @Integer
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 9223372036854775808 `Hspec.shouldBe` 9223372036854775808
-
-    Hspec.describe "TryCast Natural Float" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Float
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Natural Double" $ do
-      let f = hush . Witch.tryCast @Natural.Natural @Double
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-
-    -- Float
-
-    Hspec.describe "TryCast Float Int8" $ do
-      let f = hush . Witch.tryCast @Float @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Int16" $ do
-      let f = hush . Witch.tryCast @Float @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
-      test $ f (-32769) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Int32" $ do
-      let f = hush . Witch.tryCast @Float @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Int64" $ do
-      let f = hush . Witch.tryCast @Float @Int.Int64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Int" $ do
-      let f = hush . Witch.tryCast @Float @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Integer" $ do
-      let f = hush . Witch.tryCast @Float @Integer
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f (-16777216) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Word8" $ do
-      let f = hush . Witch.tryCast @Float @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Word16" $ do
-      let f = hush . Witch.tryCast @Float @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Word32" $ do
-      let f = hush . Witch.tryCast @Float @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Word64" $ do
-      let f = hush . Witch.tryCast @Float @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Word" $ do
-      let f = hush . Witch.tryCast @Float @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Natural" $ do
-      let f = hush . Witch.tryCast @Float @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f 16777216 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Float Rational" $ do
-      let f = hush . Witch.tryCast @Float @Rational
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f (-0) `Hspec.shouldBe` Just 0
-      test $ f 0.5 `Hspec.shouldBe` Just 0.5
-      test $ f (-0.5) `Hspec.shouldBe` Just (-0.5)
-      test $ f 16777215 `Hspec.shouldBe` Just 16777215
-      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
-      test $ f 16777216 `Hspec.shouldBe` Just 16777216
-      test $ f (-16777216) `Hspec.shouldBe` Just (-16777216)
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Float Double" $ do
-      let f = Witch.cast @Float @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 0.5 `Hspec.shouldBe` 0.5
-      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
-      test $ f (0 / 0) `Hspec.shouldSatisfy` isNaN
-      test $ f (1 / 0) `Hspec.shouldBe` (1 / 0)
-      test $ f (-1 / 0) `Hspec.shouldBe` (-1 / 0)
-
-    -- Double
-
-    Hspec.describe "TryCast Double Int8" $ do
-      let f = hush . Witch.tryCast @Double @Int.Int8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 127 `Hspec.shouldBe` Just 127
-      test $ f 128 `Hspec.shouldBe` Nothing
-      test $ f (-128) `Hspec.shouldBe` Just (-128)
-      test $ f (-129) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Int16" $ do
-      let f = hush . Witch.tryCast @Double @Int.Int16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 32767 `Hspec.shouldBe` Just 32767
-      test $ f 32768 `Hspec.shouldBe` Nothing
-      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
-      test $ f (-32769) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Int32" $ do
-      let f = hush . Witch.tryCast @Double @Int.Int32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
-      test $ f 2147483648 `Hspec.shouldBe` Nothing
-      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
-      test $ f (-2147483649) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Int64" $ do
-      let f = hush . Witch.tryCast @Double @Int.Int64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Int" $ do
-      Monad.when (toInteger (maxBound :: Int) < 9007199254740991) untested
-      let f = hush . Witch.tryCast @Double @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Integer" $ do
-      let f = hush . Witch.tryCast @Double @Integer
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Word8" $ do
-      let f = hush . Witch.tryCast @Double @Word.Word8
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 255 `Hspec.shouldBe` Just 255
-      test $ f 256 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Word16" $ do
-      let f = hush . Witch.tryCast @Double @Word.Word16
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 65535 `Hspec.shouldBe` Just 65535
-      test $ f 65536 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Word32" $ do
-      let f = hush . Witch.tryCast @Double @Word.Word32
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
-      test $ f 4294967296 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Word64" $ do
-      let f = hush . Witch.tryCast @Double @Word.Word64
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Word" $ do
-      Monad.when (toInteger (maxBound :: Word) < 9007199254740991) untested
-      let f = hush . Witch.tryCast @Double @Word
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Natural" $ do
-      let f = hush . Witch.tryCast @Double @Natural.Natural
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "TryCast Double Rational" $ do
-      let f = hush . Witch.tryCast @Double @Rational
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f (-0) `Hspec.shouldBe` Just 0
-      test $ f 0.5 `Hspec.shouldBe` Just 0.5
-      test $ f (-0.5) `Hspec.shouldBe` Just (-0.5)
-      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
-      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
-      test $ f 9007199254740992 `Hspec.shouldBe` Just 9007199254740992
-      test $ f (-9007199254740992) `Hspec.shouldBe` Just (-9007199254740992)
-      test $ f (0 / 0) `Hspec.shouldBe` Nothing
-      test $ f (1 / 0) `Hspec.shouldBe` Nothing
-      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Double Float" $ do
-      let f = Witch.cast @Double @Float
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 0.5 `Hspec.shouldBe` 0.5
-      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
-      test $ f (0 / 0) `Hspec.shouldSatisfy` isNaN
-      test $ f (1 / 0) `Hspec.shouldBe` (1 / 0)
-      test $ f (-1 / 0) `Hspec.shouldBe` (-1 / 0)
-
-    -- Ratio
-
-    Hspec.describe "Cast a (Ratio a)" $ do
-      test $ Witch.cast @Integer @Rational 0 `Hspec.shouldBe` 0
-      let f = Witch.cast @Int @(Ratio.Ratio Int)
-      test $ f 0 `Hspec.shouldBe` 0
-
-    Hspec.describe "TryCast (Ratio a) a" $ do
-      test $ hush (Witch.tryCast @Rational @Integer 0) `Hspec.shouldBe` Just 0
-      test $ hush (Witch.tryCast @Rational @Integer 0.5) `Hspec.shouldBe` Nothing
-      let f = hush . Witch.tryCast @(Ratio.Ratio Int) @Int
-      test $ f 0 `Hspec.shouldBe` Just 0
-      test $ f 0.5 `Hspec.shouldBe` Nothing
-
-    Hspec.describe "Cast Rational Float" $ do
-      let f = Witch.cast @Rational @Float
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 0.5 `Hspec.shouldBe` 0.5
-      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
-
-    Hspec.describe "Cast Rational Double" $ do
-      let f = Witch.cast @Rational @Double
-      test $ f 0 `Hspec.shouldBe` 0
-      test $ f 0.5 `Hspec.shouldBe` 0.5
-      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
-
-    -- Fixed
-
-    Hspec.describe "Cast Integer (Fixed a)" $ do
-      test $ Witch.cast @Integer @Fixed.Uni 1 `Hspec.shouldBe` 1
-      let f = Witch.cast @Integer @Fixed.Deci
-      test $ f 1 `Hspec.shouldBe` 0.1
-
-    Hspec.describe "Cast (Fixed a) Integer" $ do
-      test $ Witch.cast @Fixed.Uni @Integer 1 `Hspec.shouldBe` 1
-      let f = Witch.cast @Fixed.Deci @Integer
-      test $ f 1 `Hspec.shouldBe` 10
-
-    -- Complex
-
-    Hspec.describe "Cast a (Complex a)" $ do
-      test $ Witch.cast @Double @(Complex.Complex Double) 1 `Hspec.shouldBe` 1
-      let f = Witch.cast @Float @(Complex.Complex Float)
-      test $ f 1 `Hspec.shouldBe` 1
-
-    Hspec.describe "TryCast (Complex a) a" $ do
-      test $ hush (Witch.tryCast @(Complex.Complex Double) @Double 1) `Hspec.shouldBe` Just 1
-      test $ hush (Witch.tryCast @(Complex.Complex Double) @Double (0 Complex.:+ 1)) `Hspec.shouldBe` Nothing
-      let f = hush . Witch.tryCast @(Complex.Complex Float) @Float
-      test $ f 1 `Hspec.shouldBe` Just 1
-      test $ f (0 Complex.:+ 1) `Hspec.shouldBe` Nothing
-
-    -- NonEmpty
-
-    Hspec.describe "TryCast [a] (NonEmpty a)" $ do
-      let f = hush . Witch.tryCast @[Int] @(NonEmpty.NonEmpty Int)
-      test $ f [] `Hspec.shouldBe` Nothing
-      test $ f [1] `Hspec.shouldBe` Just (1 NonEmpty.:| [])
-      test $ f [1, 2] `Hspec.shouldBe` Just (1 NonEmpty.:| [2])
-
-    Hspec.describe "Cast (NonEmpty a) [a]" $ do
-      let f = Witch.cast @(NonEmpty.NonEmpty Int) @[Int]
-      test $ f (1 NonEmpty.:| []) `Hspec.shouldBe` [1]
-      test $ f (1 NonEmpty.:| [2]) `Hspec.shouldBe` [1, 2]
-
-    -- Set
-
-    Hspec.describe "Cast [a] (Set a)" $ do
-      let f = Witch.cast @[Char] @(Set.Set Char)
-      test $ f [] `Hspec.shouldBe` Set.fromList []
-      test $ f ['a'] `Hspec.shouldBe` Set.fromList ['a']
-      test $ f ['a', 'b'] `Hspec.shouldBe` Set.fromList ['a', 'b']
-      test $ f ['a', 'a'] `Hspec.shouldBe` Set.fromList ['a']
-
-    Hspec.describe "Cast (Set a) [a]" $ do
-      let f = Witch.cast @(Set.Set Char) @[Char]
-      test $ f (Set.fromList []) `Hspec.shouldBe` []
-      test $ f (Set.fromList ['a']) `Hspec.shouldBe` ['a']
-      test $ f (Set.fromList ['a', 'b']) `Hspec.shouldBe` ['a', 'b']
-
-    -- IntSet
-
-    Hspec.describe "Cast [Int] IntSet" $ do
-      let f = Witch.cast @[Int] @IntSet.IntSet
-      test $ f [] `Hspec.shouldBe` IntSet.fromList []
-      test $ f [1] `Hspec.shouldBe` IntSet.fromList [1]
-      test $ f [1, 2] `Hspec.shouldBe` IntSet.fromList [1, 2]
-
-    Hspec.describe "Cast IntSet [Int]" $ do
-      let f = Witch.cast @IntSet.IntSet @[Int]
-      test $ f (IntSet.fromList []) `Hspec.shouldBe` []
-      test $ f (IntSet.fromList [1]) `Hspec.shouldBe` [1]
-      test $ f (IntSet.fromList [1, 2]) `Hspec.shouldBe` [1, 2]
-
-    -- Map
-
-    Hspec.describe "Cast [(k, v)] (Map k v)" $ do
-      let f = Witch.cast @[(Char, Int)] @(Map.Map Char Int)
-      test $ f [] `Hspec.shouldBe` Map.empty
-      test $ f [('a', 1)] `Hspec.shouldBe` Map.fromList [('a', 1)]
-      test $ f [('a', 1), ('b', 2)] `Hspec.shouldBe` Map.fromList [('a', 1), ('b', 2)]
-      test $ f [('a', 1), ('a', 2)] `Hspec.shouldBe` Map.fromList [('a', 2)]
-
-    Hspec.describe "Cast (Map k v) [(k, v)]" $ do
-      let f = Witch.cast @(Map.Map Char Int) @[(Char, Int)]
-      test $ f Map.empty `Hspec.shouldBe` []
-      test $ f (Map.fromList [('a', 1)]) `Hspec.shouldBe` [('a', 1)]
-      test $ f (Map.fromList [('a', 1), ('b', 2)]) `Hspec.shouldBe` [('a', 1), ('b', 2)]
-
-    -- IntMap
-
-    Hspec.describe "Cast [(Int, v)] (IntMap v)" $ do
-      let f = Witch.cast @[(Int, Char)] @(IntMap.IntMap Char)
-      test $ f [] `Hspec.shouldBe` IntMap.fromList []
-      test $ f [(1, 'a')] `Hspec.shouldBe` IntMap.fromList [(1, 'a')]
-      test $ f [(1, 'a'), (2, 'b')] `Hspec.shouldBe` IntMap.fromList [(1, 'a'), (2, 'b')]
-      test $ f [(1, 'a'), (1, 'b')] `Hspec.shouldBe` IntMap.fromList [(1, 'b')]
-
-    Hspec.describe "Cast (IntMap v) [(Int, v)]" $ do
-      let f = Witch.cast @(IntMap.IntMap Char) @[(Int, Char)]
-      test $ f (IntMap.fromList []) `Hspec.shouldBe` []
-      test $ f (IntMap.fromList [(1, 'a')]) `Hspec.shouldBe` [(1, 'a')]
-      test $ f (IntMap.fromList [(1, 'a'), (2, 'b')]) `Hspec.shouldBe` [(1, 'a'), (2, 'b')]
-
-    -- Seq
-
-    Hspec.describe "Cast [a] (Seq a)" $ do
-      let f = Witch.cast @[Int] @(Seq.Seq Int)
-      test $ f [] `Hspec.shouldBe` Seq.fromList []
-      test $ f [1] `Hspec.shouldBe` Seq.fromList [1]
-      test $ f [1, 2] `Hspec.shouldBe` Seq.fromList [1, 2]
-
-    Hspec.describe "Cast (Seq a) [a]" $ do
-      let f = Witch.cast @(Seq.Seq Int) @[Int]
-      test $ f (Seq.fromList []) `Hspec.shouldBe` []
-      test $ f (Seq.fromList [1]) `Hspec.shouldBe` [1]
-      test $ f (Seq.fromList [1, 2]) `Hspec.shouldBe` [1, 2]
-
-    -- ByteString
-
-    Hspec.describe "Cast [Word8] ByteString" $ do
-      let f = Witch.cast @[Word.Word8] @ByteString.ByteString
-      test $ f [] `Hspec.shouldBe` ByteString.pack []
-      test $ f [0x00] `Hspec.shouldBe` ByteString.pack [0x00]
-      test $ f [0x0f, 0xf0] `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0]
-
-    Hspec.describe "Cast ByteString [Word8]" $ do
-      let f = Witch.cast @ByteString.ByteString @[Word.Word8]
-      test $ f (ByteString.pack []) `Hspec.shouldBe` []
-      test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` [0x00]
-      test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0]
-
-    Hspec.describe "Cast ByteString LazyByteString" $ do
-      let f = Witch.cast @ByteString.ByteString @LazyByteString.ByteString
-      test $ f (ByteString.pack []) `Hspec.shouldBe` LazyByteString.pack []
-      test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` LazyByteString.pack [0x00]
-      test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` LazyByteString.pack [0x0f, 0xf0]
-
-    Hspec.describe "Cast ByteString ShortByteString" $ do
-      let f = Witch.cast @ByteString.ByteString @ShortByteString.ShortByteString
-      test $ f (ByteString.pack []) `Hspec.shouldBe` ShortByteString.pack []
-      test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` ShortByteString.pack [0x00]
-      test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ShortByteString.pack [0x0f, 0xf0]
-
-    Hspec.describe "TryCast ByteString Text" $ do
-      let f = hush . Witch.tryCast @ByteString.ByteString @Text.Text
-      test $ f (ByteString.pack []) `Hspec.shouldBe` Just (Text.pack "")
-      test $ f (ByteString.pack [0x61]) `Hspec.shouldBe` Just (Text.pack "a")
-      test $ f (ByteString.pack [0xff]) `Hspec.shouldBe` Nothing
-
-    -- LazyByteString
-
-    Hspec.describe "Cast [Word8] LazyByteString" $ do
-      let f = Witch.cast @[Word.Word8] @LazyByteString.ByteString
-      test $ f [] `Hspec.shouldBe` LazyByteString.pack []
-      test $ f [0x00] `Hspec.shouldBe` LazyByteString.pack [0x00]
-      test $ f [0x0f, 0xf0] `Hspec.shouldBe` LazyByteString.pack [0x0f, 0xf0]
-
-    Hspec.describe "Cast LazyByteString [Word8]" $ do
-      let f = Witch.cast @LazyByteString.ByteString @[Word.Word8]
-      test $ f (LazyByteString.pack []) `Hspec.shouldBe` []
-      test $ f (LazyByteString.pack [0x00]) `Hspec.shouldBe` [0x00]
-      test $ f (LazyByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0]
-
-    Hspec.describe "Cast LazyByteString ByteString" $ do
-      let f = Witch.cast @LazyByteString.ByteString @ByteString.ByteString
-      test $ f (LazyByteString.pack []) `Hspec.shouldBe` ByteString.pack []
-      test $ f (LazyByteString.pack [0x00]) `Hspec.shouldBe` ByteString.pack [0x00]
-      test $ f (LazyByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0]
-
-    Hspec.describe "TryCast LazyByteString LazyText" $ do
-      let f = hush . Witch.tryCast @LazyByteString.ByteString @LazyText.Text
-      test $ f (LazyByteString.pack []) `Hspec.shouldBe` Just (LazyText.pack "")
-      test $ f (LazyByteString.pack [0x61]) `Hspec.shouldBe` Just (LazyText.pack "a")
-      test $ f (LazyByteString.pack [0xff]) `Hspec.shouldBe` Nothing
-
-    -- ShortByteString
-
-    Hspec.describe "Cast [Word8] ShortByteString" $ do
-      let f = Witch.cast @[Word.Word8] @ShortByteString.ShortByteString
-      test $ f [] `Hspec.shouldBe` ShortByteString.pack []
-      test $ f [0x00] `Hspec.shouldBe` ShortByteString.pack [0x00]
-      test $ f [0x0f, 0xf0] `Hspec.shouldBe` ShortByteString.pack [0x0f, 0xf0]
-
-    Hspec.describe "Cast ShortByteString [Word8]" $ do
-      let f = Witch.cast @ShortByteString.ShortByteString @[Word.Word8]
-      test $ f (ShortByteString.pack []) `Hspec.shouldBe` []
-      test $ f (ShortByteString.pack [0x00]) `Hspec.shouldBe` [0x00]
-      test $ f (ShortByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0]
-
-    Hspec.describe "Cast ShortByteString ByteString" $ do
-      let f = Witch.cast @ShortByteString.ShortByteString @ByteString.ByteString
-      test $ f (ShortByteString.pack []) `Hspec.shouldBe` ByteString.pack []
-      test $ f (ShortByteString.pack [0x00]) `Hspec.shouldBe` ByteString.pack [0x00]
-      test $ f (ShortByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0]
-
-    -- Text
-
-    Hspec.describe "Cast String Text" $ do
-      let f = Witch.cast @String @Text.Text
-      test $ f "" `Hspec.shouldBe` Text.pack ""
-      test $ f "a" `Hspec.shouldBe` Text.pack "a"
-      test $ f "ab" `Hspec.shouldBe` Text.pack "ab"
-
-    Hspec.describe "Cast Text String" $ do
-      let f = Witch.cast @Text.Text @String
-      test $ f (Text.pack "") `Hspec.shouldBe` ""
-      test $ f (Text.pack "a") `Hspec.shouldBe` "a"
-      test $ f (Text.pack "ab") `Hspec.shouldBe` "ab"
-
-    Hspec.describe "Cast Text LazyText" $ do
-      let f = Witch.cast @Text.Text @LazyText.Text
-      test $ f (Text.pack "") `Hspec.shouldBe` LazyText.pack ""
-      test $ f (Text.pack "a") `Hspec.shouldBe` LazyText.pack "a"
-      test $ f (Text.pack "ab") `Hspec.shouldBe` LazyText.pack "ab"
-
-    Hspec.describe "Cast Text ByteString" $ do
-      let f = Witch.cast @Text.Text @ByteString.ByteString
-      test $ f (Text.pack "") `Hspec.shouldBe` ByteString.pack []
-      test $ f (Text.pack "a") `Hspec.shouldBe` ByteString.pack [0x61]
-
-    -- LazyText
-
-    Hspec.describe "Cast String LazyText" $ do
-      let f = Witch.cast @String @LazyText.Text
-      test $ f "" `Hspec.shouldBe` LazyText.pack ""
-      test $ f "a" `Hspec.shouldBe` LazyText.pack "a"
-      test $ f "ab" `Hspec.shouldBe` LazyText.pack "ab"
-
-    Hspec.describe "Cast LazyText String" $ do
-      let f = Witch.cast @LazyText.Text @String
-      test $ f (LazyText.pack "") `Hspec.shouldBe` ""
-      test $ f (LazyText.pack "a") `Hspec.shouldBe` "a"
-      test $ f (LazyText.pack "ab") `Hspec.shouldBe` "ab"
-
-    Hspec.describe "Cast LazyText Text" $ do
-      let f = Witch.cast @LazyText.Text @Text.Text
-      test $ f (LazyText.pack "") `Hspec.shouldBe` Text.pack ""
-      test $ f (LazyText.pack "a") `Hspec.shouldBe` Text.pack "a"
-      test $ f (LazyText.pack "ab") `Hspec.shouldBe` Text.pack "ab"
-
-    Hspec.describe "Cast LazyText LazyByteString" $ do
-      let f = Witch.cast @LazyText.Text @LazyByteString.ByteString
-      test $ f (LazyText.pack "") `Hspec.shouldBe` LazyByteString.pack []
-      test $ f (LazyText.pack "a") `Hspec.shouldBe` LazyByteString.pack [0x61]
-
-    -- TryCastException
-
-    Hspec.describe "Cast (TryCastException s t0) (TryCastException s t1)" $ do
-      Hspec.it "needs tests" Hspec.pending
-
-    Hspec.describe "Cast (TryCastException s t) String" $ do
-      test $ Witch.cast (Witch.TryCastException Nothing Nothing :: Witch.TryCastException (Maybe Bool) (Maybe Int)) `Hspec.shouldBe` "TryCastException @(Maybe Bool) @(Maybe Int) Nothing Nothing"
-      let f = Witch.cast @(Witch.TryCastException Bool Int) @String
-      test $ f (Witch.TryCastException False Nothing) `Hspec.shouldBe` "TryCastException @Bool @Int False Nothing"
-
-    Hspec.describe "Cast (TryCastException s t) Text" $ do
-      let f = Witch.cast @(Witch.TryCastException Bool Int) @Text.Text
-      test $ f (Witch.TryCastException False Nothing) `Hspec.shouldBe` Text.pack "TryCastException @Bool @Int False Nothing"
-
-    Hspec.describe "Cast (TryCastException s t) LazyText" $ do
-      let f = Witch.cast @(Witch.TryCastException Bool Int) @LazyText.Text
-      test $ f (Witch.TryCastException False Nothing) `Hspec.shouldBe` LazyText.pack "TryCastException @Bool @Int False Nothing"
-
-  -- Casting
-
-  Hspec.describe "Casting" $ do
-
-    Hspec.describe "Bounded" $ do
-
-      Hspec.it "maxBound" $ do
-        maxBound `Hspec.shouldBe` Age maxBound
-
-      Hspec.it "minBound" $ do
-        minBound `Hspec.shouldBe` Age minBound
-
-    Hspec.describe "Enum" $ do
-
-      Hspec.prop "fromEnum" $ \x ->
-        fromEnum (Age x) === fromEnum x
-
-      Hspec.prop "toEnum" $ \x ->
-        toEnum x === Age (toEnum x)
-
-    Hspec.describe "Eq" $ do
-
-      Hspec.prop "==" $ \x ->
-        Age x === Age x
-
-    Hspec.describe "Ord" $ do
-
-      Hspec.prop "compare" $ \x y ->
-        compare (Age x) (Age y) === compare x y
-
-    Hspec.describe "Read" $ do
-
-      Hspec.prop "readMaybe" $ \x ->
-        Read.readMaybe x === fmap Age (Read.readMaybe x)
-
-    Hspec.describe "Show" $ do
-
-      Hspec.prop "show" $ \x ->
-        show (Age x) === show x
-
-test :: Hspec.Example a => a -> Hspec.SpecWith (Hspec.Arg a)
-test = Hspec.it ""
-
-untested :: Hspec.SpecWith a
-untested = Hspec.runIO $ Exception.throwIO Untested
-
-hush :: Either x a -> Maybe a
-hush = either (const Nothing) Just
-
-data Untested
-  = Untested
-  deriving (Eq, Show)
-
-instance Exception.Exception Untested
-
-newtype Age
-  = Age Int.Int8
-  deriving (Bounded, Enum, Eq, Ord, Read, Show) via Witch.Casting Age Int.Int8
-
-instance Witch.Cast Age Int.Int8
-
-instance Witch.Cast Int.Int8 Age
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TemplateHaskell #-}
+{-# LANGUAGE TypeApplications #-}
+
+import qualified Control.Exception as Exception
+import qualified Control.Monad as Monad
+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.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.Word as Word
+import qualified Numeric.Natural as Natural
+import qualified Test.Hspec as Hspec
+import qualified Witch
+
+main :: IO ()
+main = Hspec.hspec . Hspec.describe "Witch" $ do
+
+  Hspec.describe "From" $ do
+
+    Hspec.describe "from" $ do
+      test $ Witch.from (1 :: Int.Int8) `Hspec.shouldBe` (1 :: Int.Int16)
+
+  Hspec.describe "TryFrom" $ do
+
+    Hspec.describe "tryFrom" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8
+      test $ f 1 `Hspec.shouldBe` Just 1
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+  Hspec.describe "Utility" $ do
+
+    Hspec.describe "as" $ do
+      test $ Witch.as @Int.Int8 1 `Hspec.shouldBe` 1
+
+    Hspec.describe "from" $ do
+      test $ Witch.from @Int.Int8 1 `Hspec.shouldBe` (1 :: Int.Int16)
+
+    Hspec.describe "into" $ do
+      test $ Witch.into @Int.Int16 (1 :: Int.Int8) `Hspec.shouldBe` 1
+
+    Hspec.describe "over" $ do
+      test $ Witch.over @Int.Int8 (+ 1) (Age 1) `Hspec.shouldBe` Age 2
+
+    Hspec.describe "via" $ do
+      test $ Witch.via @Int.Int16 (1 :: Int.Int8) `Hspec.shouldBe` (1 :: Int.Int32)
+
+    Hspec.describe "tryFrom" $ do
+      test $ hush (Witch.tryFrom @Int.Int16 1) `Hspec.shouldBe` Just (1 :: Int.Int8)
+
+    Hspec.describe "tryInto" $ do
+      test $ hush (Witch.tryInto @Int.Int8 (1 :: Int.Int16)) `Hspec.shouldBe` Just 1
+
+    Hspec.describe "tryVia" $ do
+      let f = Witch.tryVia @Int.Int16 @Int.Int32 @Int.Int8
+      test $ hush (f 1) `Hspec.shouldBe` Just 1
+      test $ hush (f 128) `Hspec.shouldBe` Nothing
+      test $ hush (f 32768) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "unsafeFrom" $ do
+      test $ Witch.unsafeFrom (1 :: Int.Int16) `Hspec.shouldBe` (1 :: Int.Int8)
+      test $ Exception.evaluate (Witch.unsafeFrom @Int.Int16 @Int.Int8 128) `Hspec.shouldThrow` Hspec.anyException
+
+    Hspec.describe "unsafeInto" $ do
+      test $ Witch.unsafeInto @Int.Int8 (1 :: Int.Int16) `Hspec.shouldBe` 1
+
+  Hspec.describe "Lift" $ do
+
+    Hspec.describe "liftedFrom" $ do
+      test $ ($$(Witch.liftedFrom (1 :: Int.Int16)) :: Int.Int8) `Hspec.shouldBe` 1
+
+    Hspec.describe "liftedInto" $ do
+      test $ $$(Witch.liftedInto @Int.Int8 (1 :: Int.Int16)) `Hspec.shouldBe` 1
+
+  Hspec.describe "Instances" $ do
+
+    -- Int8
+
+    Hspec.describe "From Int8 Int16" $ do
+      let f = Witch.from @Int.Int8 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    Hspec.describe "From Int8 Int32" $ do
+      let f = Witch.from @Int.Int8 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    Hspec.describe "From Int8 Int64" $ do
+      let f = Witch.from @Int.Int8 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    Hspec.describe "From Int8 Int" $ do
+      let f = Witch.from @Int.Int8 @Int
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    Hspec.describe "From Int8 Integer" $ do
+      let f = Witch.from @Int.Int8 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    Hspec.describe "TryFrom Int8 Word8" $ do
+      let f = hush . Witch.tryFrom @Int.Int8 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int8 Word16" $ do
+      let f = hush . Witch.tryFrom @Int.Int8 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int8 Word32" $ do
+      let f = hush . Witch.tryFrom @Int.Int8 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int8 Word64" $ do
+      let f = hush . Witch.tryFrom @Int.Int8 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int8 Word" $ do
+      let f = hush . Witch.tryFrom @Int.Int8 @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int8 Natural" $ do
+      let f = hush . Witch.tryFrom @Int.Int8 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Int8 Float" $ do
+      let f = Witch.from @Int.Int8 @Float
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    Hspec.describe "From Int8 Double" $ do
+      let f = Witch.from @Int.Int8 @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 127 `Hspec.shouldBe` 127
+      test $ f (-128) `Hspec.shouldBe` (-128)
+
+    -- Int16
+
+    Hspec.describe "TryFrom Int16 Int8" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Int16 Int32" $ do
+      let f = Witch.from @Int.Int16 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 32767 `Hspec.shouldBe` 32767
+      test $ f (-32768) `Hspec.shouldBe` (-32768)
+
+    Hspec.describe "From Int16 Int64" $ do
+      let f = Witch.from @Int.Int16 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 32767 `Hspec.shouldBe` 32767
+      test $ f (-32768) `Hspec.shouldBe` (-32768)
+
+    Hspec.describe "From Int16 Int" $ do
+      let f = Witch.from @Int.Int16 @Int
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 32767 `Hspec.shouldBe` 32767
+      test $ f (-32768) `Hspec.shouldBe` (-32768)
+
+    Hspec.describe "From Int16 Integer" $ do
+      let f = Witch.from @Int.Int16 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 32767 `Hspec.shouldBe` 32767
+      test $ f (-32768) `Hspec.shouldBe` (-32768)
+
+    Hspec.describe "TryFrom Int16 Word8" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int16 Word16" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int16 Word32" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int16 Word64" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int16 Word" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int16 Natural" $ do
+      let f = hush . Witch.tryFrom @Int.Int16 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Int16 Float" $ do
+      let f = Witch.from @Int.Int16 @Float
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 32767 `Hspec.shouldBe` 32767
+      test $ f (-32768) `Hspec.shouldBe` (-32768)
+
+    Hspec.describe "From Int16 Double" $ do
+      let f = Witch.from @Int.Int16 @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 32767 `Hspec.shouldBe` 32767
+      test $ f (-32768) `Hspec.shouldBe` (-32768)
+
+    -- Int32
+
+    Hspec.describe "TryFrom Int32 Int8" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Int16" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
+      test $ f (-32769) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Int32 Int64" $ do
+      let f = Witch.from @Int.Int32 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 2147483647 `Hspec.shouldBe` 2147483647
+      test $ f (-2147483648) `Hspec.shouldBe` (-2147483648)
+
+    Hspec.describe "TryFrom Int32 Int" $ do
+      Monad.when (toInteger (maxBound :: Int) < 2147483647) untested
+      let f = hush . Witch.tryFrom @Int.Int32 @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
+
+    Hspec.describe "From Int32 Integer" $ do
+      let f = Witch.from @Int.Int32 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 2147483647 `Hspec.shouldBe` 2147483647
+      test $ f (-2147483648) `Hspec.shouldBe` (-2147483648)
+
+    Hspec.describe "TryFrom Int32 Word8" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Word16" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Word32" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Word64" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Word" $ do
+      Monad.when (toInteger (maxBound :: Word) < 2147483647) untested
+      let f = hush . Witch.tryFrom @Int.Int32 @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Natural" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int32 Float" $ do
+      let f = hush . Witch.tryFrom @Int.Int32 @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Int32 Double" $ do
+      let f = Witch.from @Int.Int32 @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 2147483647 `Hspec.shouldBe` 2147483647
+      test $ f (-2147483648) `Hspec.shouldBe` (-2147483648)
+
+    -- Int64
+
+    Hspec.describe "TryFrom Int64 Int8" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Int16" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
+      test $ f (-32769) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Int32" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
+      test $ f (-2147483649) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Int" $ do
+      Monad.when (toInteger (maxBound :: Int) < 9223372036854775807) untested
+      let f = hush . Witch.tryFrom @Int.Int64 @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f (-9223372036854775808) `Hspec.shouldBe` Just (-9223372036854775808)
+
+    Hspec.describe "From Int64 Integer" $ do
+      let f = Witch.from @Int.Int64 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` 9223372036854775807
+      test $ f (-9223372036854775808) `Hspec.shouldBe` (-9223372036854775808)
+
+    Hspec.describe "TryFrom Int64 Word8" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Word16" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Word32" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Word64" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Word" $ do
+      Monad.when (toInteger (maxBound :: Word) < 9223372036854775807) untested
+      let f = hush . Witch.tryFrom @Int.Int64 @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Natural" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Float" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int64 Double" $ do
+      let f = hush . Witch.tryFrom @Int.Int64 @Double
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
+
+    -- Int
+
+    Hspec.describe "TryFrom Int Int8" $ do
+      let f = hush . Witch.tryFrom @Int @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Int16" $ do
+      let f = hush . Witch.tryFrom @Int @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
+      test $ f (-32769) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Int32" $ do
+      Monad.when (toInteger (maxBound :: Int) < 2147483647) untested
+      let f = hush . Witch.tryFrom @Int @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
+      test $ f (-2147483649) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Int Int64" $ do
+      let f = Witch.from @Int @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Int)
+      test $ f minBound `Hspec.shouldBe` fromIntegral (minBound :: Int)
+
+    Hspec.describe "From Int Integer" $ do
+      let f = Witch.from @Int @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Int)
+      test $ f minBound `Hspec.shouldBe` fromIntegral (minBound :: Int)
+
+    Hspec.describe "TryFrom Int Word8" $ do
+      let f = hush . Witch.tryFrom @Int @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Word16" $ do
+      let f = hush . Witch.tryFrom @Int @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Word32" $ do
+      Monad.when (toInteger (maxBound :: Int) < 4294967295) untested
+      let f = hush . Witch.tryFrom @Int @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+      test $ f 4294967296 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Word64" $ do
+      let f = hush . Witch.tryFrom @Int @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f maxBound `Hspec.shouldBe` Just (fromIntegral (maxBound :: Int))
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Word" $ do
+      let f = hush . Witch.tryFrom @Int @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f maxBound `Hspec.shouldBe` Just (fromIntegral (maxBound :: Int))
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Natural" $ do
+      let f = hush . Witch.tryFrom @Int @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f maxBound `Hspec.shouldBe` Just (fromIntegral (maxBound :: Int))
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Float" $ do
+      let f = hush . Witch.tryFrom @Int @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Int Double" $ do
+      Monad.when (toInteger (maxBound :: Int) < 9007199254740991) untested
+      let f = hush . Witch.tryFrom @Int @Double
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
+
+    -- Integer
+
+    Hspec.describe "TryFrom Integer Int8" $ do
+      let f = hush . Witch.tryFrom @Integer @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Int16" $ do
+      let f = hush . Witch.tryFrom @Integer @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
+      test $ f (-32769) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Int32" $ do
+      let f = hush . Witch.tryFrom @Integer @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
+      test $ f (-2147483649) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Int64" $ do
+      let f = hush . Witch.tryFrom @Integer @Int.Int64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
+      test $ f (-9223372036854775808) `Hspec.shouldBe` Just (-9223372036854775808)
+      test $ f (-9223372036854775809) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Int" $ do
+      let f = hush . Witch.tryFrom @Integer @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ let x = maxBound :: Int in f (fromIntegral x) `Hspec.shouldBe` Just x
+      test $ let x = toInteger (maxBound :: Int) + 1 in f x `Hspec.shouldBe` Nothing
+      test $ let x = minBound :: Int in f (fromIntegral x) `Hspec.shouldBe` Just x
+      test $ let x = toInteger (minBound :: Int) - 1 in f x `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Word8" $ do
+      let f = hush . Witch.tryFrom @Integer @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Word16" $ do
+      let f = hush . Witch.tryFrom @Integer @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Word32" $ do
+      let f = hush . Witch.tryFrom @Integer @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+      test $ f 4294967296 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Word64" $ do
+      let f = hush . Witch.tryFrom @Integer @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 18446744073709551615 `Hspec.shouldBe` Just 18446744073709551615
+      test $ f 18446744073709551616 `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Word" $ do
+      let f = hush . Witch.tryFrom @Integer @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ let x = maxBound :: Word in f (fromIntegral x) `Hspec.shouldBe` Just x
+      test $ let x = toInteger (maxBound :: Word) + 1 in f x `Hspec.shouldBe` Nothing
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Natural" $ do
+      let f = hush . Witch.tryFrom @Integer @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 18446744073709551616 `Hspec.shouldBe` Just 18446744073709551616
+      test $ f (-1) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Float" $ do
+      let f = hush . Witch.tryFrom @Integer @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Integer Double" $ do
+      let f = hush . Witch.tryFrom @Integer @Double
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
+
+    -- Word8
+
+    Hspec.describe "From Word8 Word16" $ do
+      let f = Witch.from @Word.Word8 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Word32" $ do
+      let f = Witch.from @Word.Word8 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Word64" $ do
+      let f = Witch.from @Word.Word8 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Word" $ do
+      let f = Witch.from @Word.Word8 @Word
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Natural" $ do
+      let f = Witch.from @Word.Word8 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "TryFrom Word8 Int8" $ do
+      let f = hush . Witch.tryFrom @Word.Word8 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word8 Int16" $ do
+      let f = Witch.from @Word.Word8 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Int32" $ do
+      let f = Witch.from @Word.Word8 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Int64" $ do
+      let f = Witch.from @Word.Word8 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Int" $ do
+      let f = Witch.from @Word.Word8 @Int
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Integer" $ do
+      let f = Witch.from @Word.Word8 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Float" $ do
+      let f = Witch.from @Word.Word8 @Float
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    Hspec.describe "From Word8 Double" $ do
+      let f = Witch.from @Word.Word8 @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 255 `Hspec.shouldBe` 255
+
+    -- Word16
+
+    Hspec.describe "TryFrom Word16 Word8" $ do
+      let f = hush . Witch.tryFrom @Word.Word16 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word16 Word32" $ do
+      let f = Witch.from @Word.Word16 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Word64" $ do
+      let f = Witch.from @Word.Word16 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Word" $ do
+      let f = Witch.from @Word.Word16 @Word
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Natural" $ do
+      let f = Witch.from @Word.Word16 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "TryFrom Word16 Int8" $ do
+      let f = hush . Witch.tryFrom @Word.Word16 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word16 Int16" $ do
+      let f = hush . Witch.tryFrom @Word.Word16 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word16 Int32" $ do
+      let f = Witch.from @Word.Word16 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Int64" $ do
+      let f = Witch.from @Word.Word16 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Int" $ do
+      let f = Witch.from @Word.Word16 @Int
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Integer" $ do
+      let f = Witch.from @Word.Word16 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Float" $ do
+      let f = Witch.from @Word.Word16 @Float
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    Hspec.describe "From Word16 Double" $ do
+      let f = Witch.from @Word.Word16 @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 65535 `Hspec.shouldBe` 65535
+
+    -- Word32
+
+    Hspec.describe "TryFrom Word32 Word8" $ do
+      let f = hush . Witch.tryFrom @Word.Word32 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word32 Word16" $ do
+      let f = hush . Witch.tryFrom @Word.Word32 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word32 Word64" $ do
+      let f = Witch.from @Word.Word32 @Word.Word64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 4294967295 `Hspec.shouldBe` 4294967295
+
+    Hspec.describe "TryFrom Word32 Word" $ do
+      Monad.when (toInteger (maxBound :: Word) < 4294967295) untested
+      let f = hush . Witch.tryFrom @Word.Word32 @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+
+    Hspec.describe "From Word32 Natural" $ do
+      let f = Witch.from @Word.Word32 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 4294967295 `Hspec.shouldBe` 4294967295
+
+    Hspec.describe "TryFrom Word32 Int8" $ do
+      let f = hush . Witch.tryFrom @Word.Word32 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word32 Int16" $ do
+      let f = hush . Witch.tryFrom @Word.Word32 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word32 Int32" $ do
+      let f = hush . Witch.tryFrom @Word.Word32 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word32 Int64" $ do
+      let f = Witch.from @Word.Word32 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 4294967295 `Hspec.shouldBe` 4294967295
+
+    Hspec.describe "TryFrom Word32 Int" $ do
+      Monad.when (toInteger (maxBound :: Int) < 4294967295) untested
+      let f = hush . Witch.tryFrom @Word.Word32 @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+
+    Hspec.describe "From Word32 Integer" $ do
+      let f = Witch.from @Word.Word32 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 4294967295 `Hspec.shouldBe` 4294967295
+
+    Hspec.describe "TryFrom Word32 Float" $ do
+      let f = hush . Witch.tryFrom @Word.Word32 @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word32 Double" $ do
+      let f = Witch.from @Word.Word32 @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 4294967295 `Hspec.shouldBe` 4294967295
+
+    -- Word64
+
+    Hspec.describe "TryFrom Word64 Word8" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Word16" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Word32" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+      test $ f 4294967296 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Word" $ do
+      Monad.when (toInteger (maxBound :: Word) < 18446744073709551615) untested
+      let f = hush . Witch.tryFrom @Word.Word64 @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 18446744073709551615 `Hspec.shouldBe` Just 18446744073709551615
+
+    Hspec.describe "From Word64 Natural" $ do
+      let f = Witch.from @Word.Word64 @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 18446744073709551615 `Hspec.shouldBe` 18446744073709551615
+
+    Hspec.describe "TryFrom Word64 Int8" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Int16" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Int32" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Int64" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Int.Int64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Int" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ let x = maxBound :: Int in hush (Witch.tryFrom @Word.Word64 @Int (fromIntegral x)) `Hspec.shouldBe` Just x
+      test $ let x = fromIntegral (maxBound :: Int) + 1 :: Word.Word64 in hush (Witch.tryFrom @Word.Word64 @Int x) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word64 Integer" $ do
+      let f = Witch.from @Word.Word64 @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 18446744073709551615 `Hspec.shouldBe` 18446744073709551615
+
+    Hspec.describe "TryFrom Word64 Float" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word64 Double" $ do
+      let f = hush . Witch.tryFrom @Word.Word64 @Double
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+
+    -- Word
+
+    Hspec.describe "TryFrom Word Word8" $ do
+      let f = hush . Witch.tryFrom @Word @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Word16" $ do
+      let f = hush . Witch.tryFrom @Word @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Word32" $ do
+      Monad.when (toInteger (maxBound :: Word) < 4294967295) untested
+      let f = hush . Witch.tryFrom @Word @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+      test $ f 4294967296 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word Word64" $ do
+      let f = Witch.from @Word @Word.Word64
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Word)
+
+    Hspec.describe "From Word Natural" $ do
+      let f = Witch.from @Word @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Word)
+
+    Hspec.describe "TryFrom Word Int8" $ do
+      let f = hush . Witch.tryFrom @Word @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Int16" $ do
+      let f = hush . Witch.tryFrom @Word @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Int32" $ do
+      Monad.when (toInteger (maxBound :: Word) < 2147483647) untested
+      let f = hush . Witch.tryFrom @Word @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Int64" $ do
+      Monad.when (toInteger (maxBound :: Word) < 9223372036854775807) untested
+      let f = hush . Witch.tryFrom @Word @Int.Int64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Int" $ do
+      let f = hush . Witch.tryFrom @Word @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ let x = maxBound :: Int in hush (Witch.tryFrom @Word @Int (fromIntegral x)) `Hspec.shouldBe` Just x
+      test $ let x = fromIntegral (maxBound :: Int) + 1 :: Word in hush (Witch.tryFrom @Word @Int x) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Word Integer" $ do
+      let f = Witch.from @Word @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f maxBound `Hspec.shouldBe` fromIntegral (maxBound :: Word)
+
+    Hspec.describe "TryFrom Word Float" $ do
+      let f = hush . Witch.tryFrom @Word @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Word Double" $ do
+      Monad.when (toInteger (maxBound :: Word) < 9007199254740991) untested
+      let f = hush . Witch.tryFrom @Word @Double
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+
+    -- Natural
+
+    Hspec.describe "TryFrom Natural Word8" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Word16" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Word32" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+      test $ f 4294967296 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Word64" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 18446744073709551615 `Hspec.shouldBe` Just 18446744073709551615
+      test $ f 18446744073709551616 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Word" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ let x = maxBound :: Word in hush (Witch.tryFrom @Natural.Natural @Word (fromIntegral x)) `Hspec.shouldBe` Just x
+      test $ let x = fromIntegral (maxBound :: Word) + 1 :: Natural.Natural in hush (Witch.tryFrom @Natural.Natural @Word x) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Int8" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Int16" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Int32" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Int64" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Int.Int64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9223372036854775807 `Hspec.shouldBe` Just 9223372036854775807
+      test $ f 9223372036854775808 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Int" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ let x = maxBound :: Int in hush (Witch.tryFrom @Natural.Natural @Int (fromIntegral x)) `Hspec.shouldBe` Just x
+      test $ let x = fromIntegral (maxBound :: Int) + 1 :: Natural.Natural in hush (Witch.tryFrom @Natural.Natural @Int x) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Natural Integer" $ do
+      let f = Witch.from @Natural.Natural @Integer
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 9223372036854775808 `Hspec.shouldBe` 9223372036854775808
+
+    Hspec.describe "TryFrom Natural Float" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Float
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Natural Double" $ do
+      let f = hush . Witch.tryFrom @Natural.Natural @Double
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+
+    -- Float
+
+    Hspec.describe "TryFrom Float Int8" $ do
+      let f = hush . Witch.tryFrom @Float @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Int16" $ do
+      let f = hush . Witch.tryFrom @Float @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
+      test $ f (-32769) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Int32" $ do
+      let f = hush . Witch.tryFrom @Float @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Int64" $ do
+      let f = hush . Witch.tryFrom @Float @Int.Int64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Int" $ do
+      let f = hush . Witch.tryFrom @Float @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Integer" $ do
+      let f = hush . Witch.tryFrom @Float @Integer
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f (-16777216) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Word8" $ do
+      let f = hush . Witch.tryFrom @Float @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Word16" $ do
+      let f = hush . Witch.tryFrom @Float @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Word32" $ do
+      let f = hush . Witch.tryFrom @Float @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Word64" $ do
+      let f = hush . Witch.tryFrom @Float @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Word" $ do
+      let f = hush . Witch.tryFrom @Float @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Natural" $ do
+      let f = hush . Witch.tryFrom @Float @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f 16777216 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Float Rational" $ do
+      let f = hush . Witch.tryFrom @Float @Rational
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f (-0) `Hspec.shouldBe` Just 0
+      test $ f 0.5 `Hspec.shouldBe` Just 0.5
+      test $ f (-0.5) `Hspec.shouldBe` Just (-0.5)
+      test $ f 16777215 `Hspec.shouldBe` Just 16777215
+      test $ f (-16777215) `Hspec.shouldBe` Just (-16777215)
+      test $ f 16777216 `Hspec.shouldBe` Just 16777216
+      test $ f (-16777216) `Hspec.shouldBe` Just (-16777216)
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Float Double" $ do
+      let f = Witch.from @Float @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 0.5 `Hspec.shouldBe` 0.5
+      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
+      test $ f (0 / 0) `Hspec.shouldSatisfy` isNaN
+      test $ f (1 / 0) `Hspec.shouldBe` (1 / 0)
+      test $ f (-1 / 0) `Hspec.shouldBe` (-1 / 0)
+
+    -- Double
+
+    Hspec.describe "TryFrom Double Int8" $ do
+      let f = hush . Witch.tryFrom @Double @Int.Int8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 127 `Hspec.shouldBe` Just 127
+      test $ f 128 `Hspec.shouldBe` Nothing
+      test $ f (-128) `Hspec.shouldBe` Just (-128)
+      test $ f (-129) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Int16" $ do
+      let f = hush . Witch.tryFrom @Double @Int.Int16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 32767 `Hspec.shouldBe` Just 32767
+      test $ f 32768 `Hspec.shouldBe` Nothing
+      test $ f (-32768) `Hspec.shouldBe` Just (-32768)
+      test $ f (-32769) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Int32" $ do
+      let f = hush . Witch.tryFrom @Double @Int.Int32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 2147483647 `Hspec.shouldBe` Just 2147483647
+      test $ f 2147483648 `Hspec.shouldBe` Nothing
+      test $ f (-2147483648) `Hspec.shouldBe` Just (-2147483648)
+      test $ f (-2147483649) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Int64" $ do
+      let f = hush . Witch.tryFrom @Double @Int.Int64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Int" $ do
+      Monad.when (toInteger (maxBound :: Int) < 9007199254740991) untested
+      let f = hush . Witch.tryFrom @Double @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Integer" $ do
+      let f = hush . Witch.tryFrom @Double @Integer
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f (-9007199254740992) `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Word8" $ do
+      let f = hush . Witch.tryFrom @Double @Word.Word8
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 255 `Hspec.shouldBe` Just 255
+      test $ f 256 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Word16" $ do
+      let f = hush . Witch.tryFrom @Double @Word.Word16
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 65535 `Hspec.shouldBe` Just 65535
+      test $ f 65536 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Word32" $ do
+      let f = hush . Witch.tryFrom @Double @Word.Word32
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 4294967295 `Hspec.shouldBe` Just 4294967295
+      test $ f 4294967296 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Word64" $ do
+      let f = hush . Witch.tryFrom @Double @Word.Word64
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Word" $ do
+      Monad.when (toInteger (maxBound :: Word) < 9007199254740991) untested
+      let f = hush . Witch.tryFrom @Double @Word
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Natural" $ do
+      let f = hush . Witch.tryFrom @Double @Natural.Natural
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f 9007199254740992 `Hspec.shouldBe` Nothing
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "TryFrom Double Rational" $ do
+      let f = hush . Witch.tryFrom @Double @Rational
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f (-0) `Hspec.shouldBe` Just 0
+      test $ f 0.5 `Hspec.shouldBe` Just 0.5
+      test $ f (-0.5) `Hspec.shouldBe` Just (-0.5)
+      test $ f 9007199254740991 `Hspec.shouldBe` Just 9007199254740991
+      test $ f (-9007199254740991) `Hspec.shouldBe` Just (-9007199254740991)
+      test $ f 9007199254740992 `Hspec.shouldBe` Just 9007199254740992
+      test $ f (-9007199254740992) `Hspec.shouldBe` Just (-9007199254740992)
+      test $ f (0 / 0) `Hspec.shouldBe` Nothing
+      test $ f (1 / 0) `Hspec.shouldBe` Nothing
+      test $ f (-1 / 0) `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Double Float" $ do
+      let f = Witch.from @Double @Float
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 0.5 `Hspec.shouldBe` 0.5
+      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
+      test $ f (0 / 0) `Hspec.shouldSatisfy` isNaN
+      test $ f (1 / 0) `Hspec.shouldBe` (1 / 0)
+      test $ f (-1 / 0) `Hspec.shouldBe` (-1 / 0)
+
+    -- Ratio
+
+    Hspec.describe "From a (Ratio a)" $ do
+      test $ Witch.from @Integer @Rational 0 `Hspec.shouldBe` 0
+      let f = Witch.from @Int @(Ratio.Ratio Int)
+      test $ f 0 `Hspec.shouldBe` 0
+
+    Hspec.describe "TryFrom (Ratio a) a" $ do
+      test $ hush (Witch.tryFrom @Rational @Integer 0) `Hspec.shouldBe` Just 0
+      test $ hush (Witch.tryFrom @Rational @Integer 0.5) `Hspec.shouldBe` Nothing
+      let f = hush . Witch.tryFrom @(Ratio.Ratio Int) @Int
+      test $ f 0 `Hspec.shouldBe` Just 0
+      test $ f 0.5 `Hspec.shouldBe` Nothing
+
+    Hspec.describe "From Rational Float" $ do
+      let f = Witch.from @Rational @Float
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 0.5 `Hspec.shouldBe` 0.5
+      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
+
+    Hspec.describe "From Rational Double" $ do
+      let f = Witch.from @Rational @Double
+      test $ f 0 `Hspec.shouldBe` 0
+      test $ f 0.5 `Hspec.shouldBe` 0.5
+      test $ f (-0.5) `Hspec.shouldBe` (-0.5)
+
+    -- Fixed
+
+    Hspec.describe "From Integer (Fixed a)" $ do
+      test $ Witch.from @Integer @Fixed.Uni 1 `Hspec.shouldBe` 1
+      let f = Witch.from @Integer @Fixed.Deci
+      test $ f 1 `Hspec.shouldBe` 0.1
+
+    Hspec.describe "From (Fixed a) Integer" $ do
+      test $ Witch.from @Fixed.Uni @Integer 1 `Hspec.shouldBe` 1
+      let f = Witch.from @Fixed.Deci @Integer
+      test $ f 1 `Hspec.shouldBe` 10
+
+    -- Complex
+
+    Hspec.describe "From a (Complex a)" $ do
+      test $ Witch.from @Double @(Complex.Complex Double) 1 `Hspec.shouldBe` 1
+      let f = Witch.from @Float @(Complex.Complex Float)
+      test $ f 1 `Hspec.shouldBe` 1
+
+    Hspec.describe "TryFrom (Complex a) a" $ do
+      test $ hush (Witch.tryFrom @(Complex.Complex Double) @Double 1) `Hspec.shouldBe` Just 1
+      test $ hush (Witch.tryFrom @(Complex.Complex Double) @Double (0 Complex.:+ 1)) `Hspec.shouldBe` Nothing
+      let f = hush . Witch.tryFrom @(Complex.Complex Float) @Float
+      test $ f 1 `Hspec.shouldBe` Just 1
+      test $ f (0 Complex.:+ 1) `Hspec.shouldBe` Nothing
+
+    -- NonEmpty
+
+    Hspec.describe "TryFrom [a] (NonEmpty a)" $ do
+      let f = hush . Witch.tryFrom @[Int] @(NonEmpty.NonEmpty Int)
+      test $ f [] `Hspec.shouldBe` Nothing
+      test $ f [1] `Hspec.shouldBe` Just (1 NonEmpty.:| [])
+      test $ f [1, 2] `Hspec.shouldBe` Just (1 NonEmpty.:| [2])
+
+    Hspec.describe "From (NonEmpty a) [a]" $ do
+      let f = Witch.from @(NonEmpty.NonEmpty Int) @[Int]
+      test $ f (1 NonEmpty.:| []) `Hspec.shouldBe` [1]
+      test $ f (1 NonEmpty.:| [2]) `Hspec.shouldBe` [1, 2]
+
+    -- Set
+
+    Hspec.describe "From [a] (Set a)" $ do
+      let f = Witch.from @[Char] @(Set.Set Char)
+      test $ f [] `Hspec.shouldBe` Set.fromList []
+      test $ f ['a'] `Hspec.shouldBe` Set.fromList ['a']
+      test $ f ['a', 'b'] `Hspec.shouldBe` Set.fromList ['a', 'b']
+      test $ f ['a', 'a'] `Hspec.shouldBe` Set.fromList ['a']
+
+    Hspec.describe "From (Set a) [a]" $ do
+      let f = Witch.from @(Set.Set Char) @[Char]
+      test $ f (Set.fromList []) `Hspec.shouldBe` []
+      test $ f (Set.fromList ['a']) `Hspec.shouldBe` ['a']
+      test $ f (Set.fromList ['a', 'b']) `Hspec.shouldBe` ['a', 'b']
+
+    -- IntSet
+
+    Hspec.describe "From [Int] IntSet" $ do
+      let f = Witch.from @[Int] @IntSet.IntSet
+      test $ f [] `Hspec.shouldBe` IntSet.fromList []
+      test $ f [1] `Hspec.shouldBe` IntSet.fromList [1]
+      test $ f [1, 2] `Hspec.shouldBe` IntSet.fromList [1, 2]
+
+    Hspec.describe "From IntSet [Int]" $ do
+      let f = Witch.from @IntSet.IntSet @[Int]
+      test $ f (IntSet.fromList []) `Hspec.shouldBe` []
+      test $ f (IntSet.fromList [1]) `Hspec.shouldBe` [1]
+      test $ f (IntSet.fromList [1, 2]) `Hspec.shouldBe` [1, 2]
+
+    -- Map
+
+    Hspec.describe "From [(k, v)] (Map k v)" $ do
+      let f = Witch.from @[(Char, Int)] @(Map.Map Char Int)
+      test $ f [] `Hspec.shouldBe` Map.empty
+      test $ f [('a', 1)] `Hspec.shouldBe` Map.fromList [('a', 1)]
+      test $ f [('a', 1), ('b', 2)] `Hspec.shouldBe` Map.fromList [('a', 1), ('b', 2)]
+      test $ f [('a', 1), ('a', 2)] `Hspec.shouldBe` Map.fromList [('a', 2)]
+
+    Hspec.describe "From (Map k v) [(k, v)]" $ do
+      let f = Witch.from @(Map.Map Char Int) @[(Char, Int)]
+      test $ f Map.empty `Hspec.shouldBe` []
+      test $ f (Map.fromList [('a', 1)]) `Hspec.shouldBe` [('a', 1)]
+      test $ f (Map.fromList [('a', 1), ('b', 2)]) `Hspec.shouldBe` [('a', 1), ('b', 2)]
+
+    -- IntMap
+
+    Hspec.describe "From [(Int, v)] (IntMap v)" $ do
+      let f = Witch.from @[(Int, Char)] @(IntMap.IntMap Char)
+      test $ f [] `Hspec.shouldBe` IntMap.fromList []
+      test $ f [(1, 'a')] `Hspec.shouldBe` IntMap.fromList [(1, 'a')]
+      test $ f [(1, 'a'), (2, 'b')] `Hspec.shouldBe` IntMap.fromList [(1, 'a'), (2, 'b')]
+      test $ f [(1, 'a'), (1, 'b')] `Hspec.shouldBe` IntMap.fromList [(1, 'b')]
+
+    Hspec.describe "From (IntMap v) [(Int, v)]" $ do
+      let f = Witch.from @(IntMap.IntMap Char) @[(Int, Char)]
+      test $ f (IntMap.fromList []) `Hspec.shouldBe` []
+      test $ f (IntMap.fromList [(1, 'a')]) `Hspec.shouldBe` [(1, 'a')]
+      test $ f (IntMap.fromList [(1, 'a'), (2, 'b')]) `Hspec.shouldBe` [(1, 'a'), (2, 'b')]
+
+    -- Seq
+
+    Hspec.describe "From [a] (Seq a)" $ do
+      let f = Witch.from @[Int] @(Seq.Seq Int)
+      test $ f [] `Hspec.shouldBe` Seq.fromList []
+      test $ f [1] `Hspec.shouldBe` Seq.fromList [1]
+      test $ f [1, 2] `Hspec.shouldBe` Seq.fromList [1, 2]
+
+    Hspec.describe "From (Seq a) [a]" $ do
+      let f = Witch.from @(Seq.Seq Int) @[Int]
+      test $ f (Seq.fromList []) `Hspec.shouldBe` []
+      test $ f (Seq.fromList [1]) `Hspec.shouldBe` [1]
+      test $ f (Seq.fromList [1, 2]) `Hspec.shouldBe` [1, 2]
+
+    -- ByteString
+
+    Hspec.describe "From [Word8] ByteString" $ do
+      let f = Witch.from @[Word.Word8] @ByteString.ByteString
+      test $ f [] `Hspec.shouldBe` ByteString.pack []
+      test $ f [0x00] `Hspec.shouldBe` ByteString.pack [0x00]
+      test $ f [0x0f, 0xf0] `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0]
+
+    Hspec.describe "From ByteString [Word8]" $ do
+      let f = Witch.from @ByteString.ByteString @[Word.Word8]
+      test $ f (ByteString.pack []) `Hspec.shouldBe` []
+      test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` [0x00]
+      test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0]
+
+    Hspec.describe "From ByteString LazyByteString" $ do
+      let f = Witch.from @ByteString.ByteString @LazyByteString.ByteString
+      test $ f (ByteString.pack []) `Hspec.shouldBe` LazyByteString.pack []
+      test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` LazyByteString.pack [0x00]
+      test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` LazyByteString.pack [0x0f, 0xf0]
+
+    Hspec.describe "From ByteString ShortByteString" $ do
+      let f = Witch.from @ByteString.ByteString @ShortByteString.ShortByteString
+      test $ f (ByteString.pack []) `Hspec.shouldBe` ShortByteString.pack []
+      test $ f (ByteString.pack [0x00]) `Hspec.shouldBe` ShortByteString.pack [0x00]
+      test $ f (ByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ShortByteString.pack [0x0f, 0xf0]
+
+    Hspec.describe "TryFrom ByteString Text" $ do
+      let f = hush . Witch.tryFrom @ByteString.ByteString @Text.Text
+      test $ f (ByteString.pack []) `Hspec.shouldBe` Just (Text.pack "")
+      test $ f (ByteString.pack [0x61]) `Hspec.shouldBe` Just (Text.pack "a")
+      test $ f (ByteString.pack [0xff]) `Hspec.shouldBe` Nothing
+
+    -- LazyByteString
+
+    Hspec.describe "From [Word8] LazyByteString" $ do
+      let f = Witch.from @[Word.Word8] @LazyByteString.ByteString
+      test $ f [] `Hspec.shouldBe` LazyByteString.pack []
+      test $ f [0x00] `Hspec.shouldBe` LazyByteString.pack [0x00]
+      test $ f [0x0f, 0xf0] `Hspec.shouldBe` LazyByteString.pack [0x0f, 0xf0]
+
+    Hspec.describe "From LazyByteString [Word8]" $ do
+      let f = Witch.from @LazyByteString.ByteString @[Word.Word8]
+      test $ f (LazyByteString.pack []) `Hspec.shouldBe` []
+      test $ f (LazyByteString.pack [0x00]) `Hspec.shouldBe` [0x00]
+      test $ f (LazyByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0]
+
+    Hspec.describe "From LazyByteString ByteString" $ do
+      let f = Witch.from @LazyByteString.ByteString @ByteString.ByteString
+      test $ f (LazyByteString.pack []) `Hspec.shouldBe` ByteString.pack []
+      test $ f (LazyByteString.pack [0x00]) `Hspec.shouldBe` ByteString.pack [0x00]
+      test $ f (LazyByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0]
+
+    Hspec.describe "TryFrom LazyByteString LazyText" $ do
+      let f = hush . Witch.tryFrom @LazyByteString.ByteString @LazyText.Text
+      test $ f (LazyByteString.pack []) `Hspec.shouldBe` Just (LazyText.pack "")
+      test $ f (LazyByteString.pack [0x61]) `Hspec.shouldBe` Just (LazyText.pack "a")
+      test $ f (LazyByteString.pack [0xff]) `Hspec.shouldBe` Nothing
+
+    -- ShortByteString
+
+    Hspec.describe "From [Word8] ShortByteString" $ do
+      let f = Witch.from @[Word.Word8] @ShortByteString.ShortByteString
+      test $ f [] `Hspec.shouldBe` ShortByteString.pack []
+      test $ f [0x00] `Hspec.shouldBe` ShortByteString.pack [0x00]
+      test $ f [0x0f, 0xf0] `Hspec.shouldBe` ShortByteString.pack [0x0f, 0xf0]
+
+    Hspec.describe "From ShortByteString [Word8]" $ do
+      let f = Witch.from @ShortByteString.ShortByteString @[Word.Word8]
+      test $ f (ShortByteString.pack []) `Hspec.shouldBe` []
+      test $ f (ShortByteString.pack [0x00]) `Hspec.shouldBe` [0x00]
+      test $ f (ShortByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` [0x0f, 0xf0]
+
+    Hspec.describe "From ShortByteString ByteString" $ do
+      let f = Witch.from @ShortByteString.ShortByteString @ByteString.ByteString
+      test $ f (ShortByteString.pack []) `Hspec.shouldBe` ByteString.pack []
+      test $ f (ShortByteString.pack [0x00]) `Hspec.shouldBe` ByteString.pack [0x00]
+      test $ f (ShortByteString.pack [0x0f, 0xf0]) `Hspec.shouldBe` ByteString.pack [0x0f, 0xf0]
+
+    -- Text
+
+    Hspec.describe "From String Text" $ do
+      let f = Witch.from @String @Text.Text
+      test $ f "" `Hspec.shouldBe` Text.pack ""
+      test $ f "a" `Hspec.shouldBe` Text.pack "a"
+      test $ f "ab" `Hspec.shouldBe` Text.pack "ab"
+
+    Hspec.describe "From Text String" $ do
+      let f = Witch.from @Text.Text @String
+      test $ f (Text.pack "") `Hspec.shouldBe` ""
+      test $ f (Text.pack "a") `Hspec.shouldBe` "a"
+      test $ f (Text.pack "ab") `Hspec.shouldBe` "ab"
+
+    Hspec.describe "From Text LazyText" $ do
+      let f = Witch.from @Text.Text @LazyText.Text
+      test $ f (Text.pack "") `Hspec.shouldBe` LazyText.pack ""
+      test $ f (Text.pack "a") `Hspec.shouldBe` LazyText.pack "a"
+      test $ f (Text.pack "ab") `Hspec.shouldBe` LazyText.pack "ab"
+
+    Hspec.describe "From Text ByteString" $ do
+      let f = Witch.from @Text.Text @ByteString.ByteString
+      test $ f (Text.pack "") `Hspec.shouldBe` ByteString.pack []
+      test $ f (Text.pack "a") `Hspec.shouldBe` ByteString.pack [0x61]
+
+    -- LazyText
+
+    Hspec.describe "From String LazyText" $ do
+      let f = Witch.from @String @LazyText.Text
+      test $ f "" `Hspec.shouldBe` LazyText.pack ""
+      test $ f "a" `Hspec.shouldBe` LazyText.pack "a"
+      test $ f "ab" `Hspec.shouldBe` LazyText.pack "ab"
+
+    Hspec.describe "From LazyText String" $ do
+      let f = Witch.from @LazyText.Text @String
+      test $ f (LazyText.pack "") `Hspec.shouldBe` ""
+      test $ f (LazyText.pack "a") `Hspec.shouldBe` "a"
+      test $ f (LazyText.pack "ab") `Hspec.shouldBe` "ab"
+
+    Hspec.describe "From LazyText Text" $ do
+      let f = Witch.from @LazyText.Text @Text.Text
+      test $ f (LazyText.pack "") `Hspec.shouldBe` Text.pack ""
+      test $ f (LazyText.pack "a") `Hspec.shouldBe` Text.pack "a"
+      test $ f (LazyText.pack "ab") `Hspec.shouldBe` Text.pack "ab"
+
+    Hspec.describe "From LazyText LazyByteString" $ do
+      let f = Witch.from @LazyText.Text @LazyByteString.ByteString
+      test $ f (LazyText.pack "") `Hspec.shouldBe` LazyByteString.pack []
+      test $ f (LazyText.pack "a") `Hspec.shouldBe` LazyByteString.pack [0x61]
+
+    -- TryFromException
+
+    Hspec.describe "From (TryFromException s t0) (TryFromException s t1)" $ do
+      Hspec.it "needs tests" Hspec.pending
+
+test :: Hspec.Example a => a -> Hspec.SpecWith (Hspec.Arg a)
+test = Hspec.it ""
+
+untested :: Hspec.SpecWith a
+untested = Hspec.runIO $ Exception.throwIO Untested
+
+hush :: Either x a -> Maybe a
+hush = either (const Nothing) Just
+
+data Untested
+  = Untested
+  deriving (Eq, Show)
+
+instance Exception.Exception Untested
+
+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,7 +1,7 @@
 cabal-version: 2.2
 
 name: witch
-version: 0.2.1.1
+version: 0.3.0.0
 synopsis: Convert values from one type into another.
 description: Witch converts values from one type into another.
 
@@ -25,6 +25,7 @@
   default-language: Haskell2010
   ghc-options:
     -Weverything
+    -Wno-all-missed-specialisations
     -Wno-implicit-prelude
     -Wno-missing-deriving-strategies
     -Wno-missing-export-lists
@@ -45,13 +46,11 @@
     , template-haskell >= 2.15.0 && < 2.18
   exposed-modules:
     Witch
-    Witch.Cast
-    Witch.Casting
-    Witch.Identity
+    Witch.From
     Witch.Instances
     Witch.Lift
-    Witch.TryCast
-    Witch.TryCastException
+    Witch.TryFrom
+    Witch.TryFromException
     Witch.Utility
   hs-source-dirs: src/lib
 
@@ -68,7 +67,6 @@
 
   build-depends:
     , hspec >= 2.7.9 && < 2.8
-    , QuickCheck >= 2.14.2 && < 2.15
     , witch
   ghc-options:
     -rtsopts
