packages feed

witch 0.3.4.2 → 1.0.0.1

raw patch · 23 files changed

+4024/−3947 lines, 23 filesdep ~HUnitPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: HUnit

API changes (from Hackage documentation)

- Witch.Instances: instance Witch.From.From (Witch.TryFromException.TryFromException s u) (Witch.TryFromException.TryFromException s t)
+ Witch.Instances: instance Witch.From.From (Witch.TryFromException.TryFromException source oldTarget) (Witch.TryFromException.TryFromException source newTarget)
+ Witch.Utility: withSource :: newSource -> TryFromException oldSource target -> TryFromException newSource target
+ Witch.Utility: withTarget :: forall newTarget source oldTarget. TryFromException source oldTarget -> TryFromException source newTarget

Files

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