From cdd86e9e2f7747e9fafba35e372fc900a781f846 Mon Sep 17 00:00:00 2001 From: Taylor Fausak Date: Mon, 10 May 2021 21:04:51 -0400 Subject: [PATCH] Replace "cast" functions with "from" --- src/ghc-8.10/Witch/Lift.hs | 28 +---- src/ghc-8.8/Witch/Lift.hs | 28 +---- src/ghc-9.0/Witch/Lift.hs | 29 +---- src/lib/Witch.hs | 8 +- src/lib/Witch/Instances.hs | 228 ++++++++++++++++++------------------- src/lib/Witch/TryFrom.hs | 2 +- src/lib/Witch/Utility.hs | 38 ++----- src/test/Main.hs | 12 +- 8 files changed, 142 insertions(+), 231 deletions(-) diff --git a/src/ghc-8.10/Witch/Lift.hs b/src/ghc-8.10/Witch/Lift.hs index 746c62a..0977930 100644 --- a/src/ghc-8.10/Witch/Lift.hs +++ b/src/ghc-8.10/Witch/Lift.hs @@ -7,34 +7,14 @@ import qualified Language.Haskell.TH.Syntax as TH import qualified Witch.TryFrom as TryFrom import qualified Witch.Utility as Utility --- | This is like 'Utility.unsafeCast' except that it works at compile time --- rather than runtime. --- --- > -- Avoid this: --- > unsafeCast "some literal" --- > --- > -- Prefer this: --- > $$(liftedCast "some literal") -liftedCast - :: forall source target - . ( TryFrom.TryFrom source target - , TH.Lift target - , Show source - , Typeable.Typeable source - , Typeable.Typeable target - ) - => source - -> TH.Q (TH.TExp target) -liftedCast = TH.liftTyped . Utility.unsafeCast - -- | This is like 'Utility.unsafeFrom' except that it works at compile time -- rather than runtime. -- -- > -- Avoid this: --- > unsafeFrom @s "some literal" +-- > unsafeFrom "some literal" -- > -- > -- Prefer this: --- > $$(liftedFrom @s "some literal") +-- > $$(liftedFrom "some literal") liftedFrom :: forall source target . ( TryFrom.TryFrom source target @@ -45,7 +25,7 @@ liftedFrom ) => source -> TH.Q (TH.TExp target) -liftedFrom = liftedCast +liftedFrom = TH.liftTyped . Utility.unsafeFrom -- | This is like 'Utility.unsafeInto' except that it works at compile time -- rather than runtime. @@ -65,4 +45,4 @@ liftedInto ) => source -> TH.Q (TH.TExp target) -liftedInto = liftedCast +liftedInto = liftedFrom diff --git a/src/ghc-8.8/Witch/Lift.hs b/src/ghc-8.8/Witch/Lift.hs index c6ed5ed..1f1370e 100644 --- a/src/ghc-8.8/Witch/Lift.hs +++ b/src/ghc-8.8/Witch/Lift.hs @@ -7,34 +7,14 @@ import qualified Language.Haskell.TH.Syntax as TH import qualified Witch.TryFrom as TryFrom import qualified Witch.Utility as Utility --- | This is like 'Utility.unsafeCast' except that it works at compile time --- rather than runtime. --- --- > -- Avoid this: --- > unsafeCast "some literal" --- > --- > -- Prefer this: --- > $$(liftedCast "some literal") -liftedCast - :: forall source target - . ( TryFrom.TryFrom source target - , TH.Lift target - , Show source - , Typeable.Typeable source - , Typeable.Typeable target - ) - => source - -> TH.Q (TH.TExp target) -liftedCast s = TH.unsafeTExpCoerce $ TH.lift (Utility.unsafeCast s :: target) - -- | This is like 'Utility.unsafeFrom' except that it works at compile time -- rather than runtime. -- -- > -- Avoid this: --- > unsafeFrom @s "some literal" +-- > unsafeFrom "some literal" -- > -- > -- Prefer this: --- > $$(liftedFrom @s "some literal") +-- > $$(liftedFrom "some literal") liftedFrom :: forall source target . ( TryFrom.TryFrom source target @@ -45,7 +25,7 @@ liftedFrom ) => source -> TH.Q (TH.TExp target) -liftedFrom = liftedCast +liftedFrom s = TH.unsafeTExpCoerce $ TH.lift (Utility.unsafeFrom s :: target) -- | This is like 'Utility.unsafeInto' except that it works at compile time -- rather than runtime. @@ -65,4 +45,4 @@ liftedInto ) => source -> TH.Q (TH.TExp target) -liftedInto = liftedCast +liftedInto = liftedFrom diff --git a/src/ghc-9.0/Witch/Lift.hs b/src/ghc-9.0/Witch/Lift.hs index 04b5bd8..c40b02a 100644 --- a/src/ghc-9.0/Witch/Lift.hs +++ b/src/ghc-9.0/Witch/Lift.hs @@ -7,35 +7,14 @@ import qualified Language.Haskell.TH.Syntax as TH import qualified Witch.TryFrom as TryFrom import qualified Witch.Utility as Utility --- | This is like 'Utility.unsafeCast' except that it works at compile time --- rather than runtime. --- --- > -- Avoid this: --- > unsafeCast "some literal" --- > --- > -- Prefer this: --- > $$(liftedCast "some literal") -liftedCast - :: forall source target m - . ( TryFrom.TryFrom source target - , TH.Lift target - , Show source - , Typeable.Typeable source - , Typeable.Typeable target - , TH.Quote m - ) - => source - -> TH.Code m target -liftedCast = TH.liftTyped . Utility.unsafeCast - -- | This is like 'Utility.unsafeFrom' except that it works at compile time -- rather than runtime. -- -- > -- Avoid this: --- > unsafeFrom @s "some literal" +-- > unsafeFrom "some literal" -- > -- > -- Prefer this: --- > $$(liftedFrom @s "some literal") +-- > $$(liftedFrom "some literal") liftedFrom :: forall source target m . ( TryFrom.TryFrom source target @@ -47,7 +26,7 @@ liftedFrom ) => source -> TH.Code m target -liftedFrom = liftedCast +liftedFrom = TH.liftTyped . Utility.unsafeFrom -- | This is like 'Utility.unsafeInto' except that it works at compile time -- rather than runtime. @@ -68,4 +47,4 @@ liftedInto ) => source -> TH.Code m target -liftedInto = liftedCast +liftedInto = liftedFrom diff --git a/src/lib/Witch.hs b/src/lib/Witch.hs index 9295d81..5b5beda 100644 --- a/src/lib/Witch.hs +++ b/src/lib/Witch.hs @@ -24,8 +24,8 @@ module Witch , Witch.Utility.over , Witch.Utility.via , Witch.Utility.tryVia - , Witch.Utility.maybeTryCast - , Witch.Utility.eitherTryCast + , Witch.Utility.maybeTryFrom + , Witch.Utility.eitherTryFrom -- ** Unsafe -- | These functions should only be used in two circumstances: When you know @@ -34,8 +34,7 @@ module Witch -- In all other cases you should prefer the normal conversion functions like -- 'Witch.From.from'. And if you're converting a literal value, consider -- using the Template Haskell conversion functions like - -- 'Witch.Lift.liftedCast'. - , Witch.Utility.unsafeCast + -- 'Witch.Lift.liftedFrom'. , Witch.Utility.unsafeFrom , Witch.Utility.unsafeInto @@ -46,7 +45,6 @@ module Witch -- variant uses the @$$(...)@ syntax for splices, doubling up on the dollar -- signs. Other than that, using typed Template Haskell should be pretty -- much the same as using regular Template Haskell. - , Witch.Lift.liftedCast , Witch.Lift.liftedFrom , Witch.Lift.liftedInto diff --git a/src/lib/Witch/Instances.hs b/src/lib/Witch/Instances.hs index a6d462f..9601103 100644 --- a/src/lib/Witch/Instances.hs +++ b/src/lib/Witch/Instances.hs @@ -58,27 +58,27 @@ instance From.From Int.Int8 Integer where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int8 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int8 Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int8 Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int8 Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int8 Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral' when the input is not negative. instance TryFrom.TryFrom Int.Int8 Natural.Natural where - tryFrom = Utility.eitherTryCast fromNonNegativeIntegral + tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral -- | Uses 'fromIntegral'. instance From.From Int.Int8 Float where @@ -92,7 +92,7 @@ instance From.From Int.Int8 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int16 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Int.Int16 Int.Int32 where @@ -112,27 +112,27 @@ instance From.From Int.Int16 Integer where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int16 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int16 Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int16 Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int16 Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int16 Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral' when the input is not negative. instance TryFrom.TryFrom Int.Int16 Natural.Natural where - tryFrom = Utility.eitherTryCast fromNonNegativeIntegral + tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral -- | Uses 'fromIntegral'. instance From.From Int.Int16 Float where @@ -146,11 +146,11 @@ instance From.From Int.Int16 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Int.Int32 Int.Int64 where @@ -158,7 +158,7 @@ instance From.From Int.Int32 Int.Int64 where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Int.Int32 Integer where @@ -166,32 +166,32 @@ instance From.From Int.Int32 Integer where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int32 Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral' when the input is not negative. instance TryFrom.TryFrom Int.Int32 Natural.Natural where - tryFrom = Utility.eitherTryCast fromNonNegativeIntegral + 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.eitherTryCast $ \s -> if s < -maxFloat + tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat then Left Exception.Underflow else if s > maxFloat then Left Exception.Overflow @@ -205,19 +205,19 @@ instance From.From Int.Int32 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Int.Int64 Integer where @@ -225,32 +225,32 @@ instance From.From Int.Int64 Integer where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int.Int64 Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral' when the input is not negative. instance TryFrom.TryFrom Int.Int64 Natural.Natural where - tryFrom = Utility.eitherTryCast fromNonNegativeIntegral + tryFrom = Utility.eitherTryFrom fromNonNegativeIntegral -- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215 -- inclusive. instance TryFrom.TryFrom Int.Int64 Float where - tryFrom = Utility.eitherTryCast $ \s -> if s < -maxFloat + tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat then Left Exception.Underflow else if s > maxFloat then Left Exception.Overflow @@ -259,7 +259,7 @@ instance TryFrom.TryFrom Int.Int64 Float where -- | 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.eitherTryCast $ \s -> if s < -maxDouble + tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxDouble then Left Exception.Underflow else if s > maxDouble then Left Exception.Overflow @@ -269,15 +269,15 @@ instance TryFrom.TryFrom Int.Int64 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Int Int.Int64 where @@ -289,32 +289,32 @@ instance From.From Int Integer where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Int Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral' when the input is not negative. instance TryFrom.TryFrom Int Natural.Natural where - tryFrom = Utility.eitherTryCast fromNonNegativeIntegral + 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.eitherTryCast $ \s -> if s < -maxFloat + tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat then Left Exception.Underflow else if s > maxFloat then Left Exception.Overflow @@ -323,7 +323,7 @@ instance TryFrom.TryFrom Int Float where -- | 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.eitherTryCast $ \s -> + tryFrom = Utility.eitherTryFrom $ \s -> if toInteger (maxBound :: Int) <= maxDouble then Right $ fromIntegral s else if s < -maxDouble @@ -336,57 +336,57 @@ instance TryFrom.TryFrom Int Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Int.Int64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Integer Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromInteger' when the input is not negative. instance TryFrom.TryFrom Integer Natural.Natural where - -- This should use @eitherTryCast fromNonNegativeIntegral@, but that causes + -- 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.eitherTryCast + tryFrom = Utility.eitherTryFrom $ \s -> if s < 0 then Left Exception.Underflow else Right $ fromInteger s -- | Uses 'fromIntegral' when the input is between -16,777,215 and 16,777,215 -- inclusive. instance TryFrom.TryFrom Integer Float where - tryFrom = Utility.eitherTryCast $ \s -> if s < -maxFloat + tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxFloat then Left Exception.Underflow else if s > maxFloat then Left Exception.Overflow @@ -395,7 +395,7 @@ instance TryFrom.TryFrom Integer Float where -- | 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.eitherTryCast $ \s -> if s < -maxDouble + tryFrom = Utility.eitherTryFrom $ \s -> if s < -maxDouble then Left Exception.Underflow else if s > maxDouble then Left Exception.Overflow @@ -425,7 +425,7 @@ instance From.From Word.Word8 Natural.Natural where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word8 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word8 Int.Int16 where @@ -459,7 +459,7 @@ instance From.From Word.Word8 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word16 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word16 Word.Word32 where @@ -479,11 +479,11 @@ instance From.From Word.Word16 Natural.Natural where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word16 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word16 Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word16 Int.Int32 where @@ -513,11 +513,11 @@ instance From.From Word.Word16 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word32 Word.Word64 where @@ -525,7 +525,7 @@ instance From.From Word.Word32 Word.Word64 where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word32 Natural.Natural where @@ -533,15 +533,15 @@ instance From.From Word.Word32 Natural.Natural where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word32 Int.Int64 where @@ -549,7 +549,7 @@ instance From.From Word.Word32 Int.Int64 where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word32 Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word32 Integer where @@ -557,7 +557,7 @@ instance From.From Word.Word32 Integer where -- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215. instance TryFrom.TryFrom Word.Word32 Float where - tryFrom = Utility.eitherTryCast $ \s -> + tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxFloat then Right $ fromIntegral s else Left Exception.Overflow -- | Uses 'fromIntegral'. @@ -568,19 +568,19 @@ instance From.From Word.Word32 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word64 Natural.Natural where @@ -588,23 +588,23 @@ instance From.From Word.Word64 Natural.Natural where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Int.Int64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word.Word64 Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word.Word64 Integer where @@ -612,13 +612,13 @@ instance From.From Word.Word64 Integer where -- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215. instance TryFrom.TryFrom Word.Word64 Float where - tryFrom = Utility.eitherTryCast $ \s -> + 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.eitherTryCast $ \s -> if s <= maxDouble + tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxDouble then Right $ fromIntegral s else Left Exception.Overflow @@ -626,15 +626,15 @@ instance TryFrom.TryFrom Word.Word64 Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word Word.Word64 where @@ -646,23 +646,23 @@ instance From.From Word Natural.Natural where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Int.Int64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Word Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Word Integer where @@ -670,13 +670,13 @@ instance From.From Word Integer where -- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215. instance TryFrom.TryFrom Word Float where - tryFrom = Utility.eitherTryCast $ \s -> + 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.eitherTryCast $ \s -> + tryFrom = Utility.eitherTryFrom $ \s -> if (toInteger (maxBound :: Word) <= maxDouble) || (s <= maxDouble) then Right $ fromIntegral s else Left Exception.Overflow @@ -685,43 +685,43 @@ instance TryFrom.TryFrom Word Double where -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Word.Word8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Word.Word16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Word.Word32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Word.Word64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Word where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Int.Int8 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Int.Int16 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Int.Int32 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Int.Int64 where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'Bits.toIntegralSized'. instance TryFrom.TryFrom Natural.Natural Int where - tryFrom = Utility.maybeTryCast Bits.toIntegralSized + tryFrom = Utility.maybeTryFrom Bits.toIntegralSized -- | Uses 'fromIntegral'. instance From.From Natural.Natural Integer where @@ -729,13 +729,13 @@ instance From.From Natural.Natural Integer where -- | Uses 'fromIntegral' when the input is less than or equal to 16,777,215. instance TryFrom.TryFrom Natural.Natural Float where - tryFrom = Utility.eitherTryCast $ \s -> + 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.eitherTryCast $ \s -> if s <= maxDouble + tryFrom = Utility.eitherTryFrom $ \s -> if s <= maxDouble then Right $ fromIntegral s else Left Exception.Overflow @@ -764,7 +764,7 @@ instance TryFrom.TryFrom Float Int where -- | Converts via 'Rational' when the input is between -16,777,215 and -- 16,777,215 inclusive. instance TryFrom.TryFrom Float Integer where - tryFrom = Utility.eitherTryCast $ \s -> case Utility.tryVia @Rational s of + 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 @@ -797,7 +797,7 @@ instance TryFrom.TryFrom Float Natural.Natural where -- | Uses 'toRational' when the input is not NaN or infinity. instance TryFrom.TryFrom Float Rational where - tryFrom = Utility.eitherTryCast $ \s -> if isNaN s + tryFrom = Utility.eitherTryFrom $ \s -> if isNaN s then Left Exception.LossOfPrecision else if isInfinite s then if s > 0 then Left Exception.Overflow else Left Exception.Underflow @@ -832,7 +832,7 @@ instance TryFrom.TryFrom Double Int where -- | 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.eitherTryCast $ \s -> case Utility.tryVia @Rational s of + 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 @@ -865,7 +865,7 @@ instance TryFrom.TryFrom Double Natural.Natural where -- | Uses 'toRational' when the input is not NaN or infinity. instance TryFrom.TryFrom Double Rational where - tryFrom = Utility.eitherTryCast $ \s -> if isNaN s + tryFrom = Utility.eitherTryFrom $ \s -> if isNaN s then Left Exception.LossOfPrecision else if isInfinite s then if s > 0 then Left Exception.Overflow else Left Exception.Underflow @@ -883,7 +883,7 @@ instance Integral a => From.From a (Ratio.Ratio a) where -- | Uses 'Ratio.numerator' when the denominator is 1. instance (Eq a, Num a) => TryFrom.TryFrom (Ratio.Ratio a) a where - tryFrom = Utility.eitherTryCast $ \s -> if Ratio.denominator s == 1 + tryFrom = Utility.eitherTryFrom $ \s -> if Ratio.denominator s == 1 then Right $ Ratio.numerator s else Left Exception.LossOfPrecision @@ -915,7 +915,7 @@ instance Num a => From.From a (Complex.Complex a) where -- | Uses 'Complex.realPart' when the imaginary part is 0. instance (Eq a, Num a) => TryFrom.TryFrom (Complex.Complex a) a where - tryFrom = Utility.eitherTryCast $ \s -> if Complex.imagPart s == 0 + tryFrom = Utility.eitherTryFrom $ \s -> if Complex.imagPart s == 0 then Right $ Complex.realPart s else Left Exception.LossOfPrecision @@ -923,7 +923,7 @@ instance (Eq a, Num a) => TryFrom.TryFrom (Complex.Complex a) a where -- | Uses 'NonEmpty.nonEmpty'. instance TryFrom.TryFrom [a] (NonEmpty.NonEmpty a) where - tryFrom = Utility.maybeTryCast NonEmpty.nonEmpty + tryFrom = Utility.maybeTryFrom NonEmpty.nonEmpty -- | Uses 'NonEmpty.toList'. instance From.From (NonEmpty.NonEmpty a) [a] where @@ -1001,7 +1001,7 @@ instance From.From ByteString.ByteString ShortByteString.ShortByteString where -- | Uses 'Text.decodeUtf8''. instance TryFrom.TryFrom ByteString.ByteString Text.Text where - tryFrom = Utility.eitherTryCast Text.decodeUtf8' + tryFrom = Utility.eitherTryFrom Text.decodeUtf8' -- LazyByteString @@ -1019,7 +1019,7 @@ instance From.From LazyByteString.ByteString ByteString.ByteString where -- | Uses 'LazyText.decodeUtf8''. instance TryFrom.TryFrom LazyByteString.ByteString LazyText.Text where - tryFrom = Utility.eitherTryCast LazyText.decodeUtf8' + tryFrom = Utility.eitherTryFrom LazyText.decodeUtf8' -- ShortByteString diff --git a/src/lib/Witch/TryFrom.hs b/src/lib/Witch/TryFrom.hs index 3957eb9..c3530f9 100644 --- a/src/lib/Witch/TryFrom.hs +++ b/src/lib/Witch/TryFrom.hs @@ -16,6 +16,6 @@ class TryFrom source target where -- sites you will usually want to use @tryFrom@ or @tryInto@ instead of this -- method. -- - -- Consider using @maybeTryCast@ or @eitherTryCast@ to implement this + -- Consider using @maybeTryFrom@ or @eitherTryFrom@ to implement this -- method. tryFrom :: source -> Either (TryFromException.TryFromException source target) target diff --git a/src/lib/Witch/Utility.hs b/src/lib/Witch/Utility.hs index 62a804a..5dde7b4 100644 --- a/src/lib/Witch/Utility.hs +++ b/src/lib/Witch/Utility.hs @@ -128,12 +128,12 @@ tryVia s = case TryFrom.tryFrom s of -- > Just t -> Right t -- > -- > -- Prefer this: --- > tryFrom = maybeTryCast f -maybeTryCast +-- > tryFrom = maybeTryFrom f +maybeTryFrom :: (source -> Maybe target) -> source -> Either (TryFromException.TryFromException source target) target -maybeTryCast f s = case f s of +maybeTryFrom f s = case f s of Nothing -> Left $ TryFromException.TryFromException s Nothing Just t -> Right t @@ -146,13 +146,13 @@ maybeTryCast f s = case f s of -- > Right t -> Right t -- > -- > -- Prefer this: --- > tryFrom = eitherTryCast f -eitherTryCast +-- > tryFrom = eitherTryFrom f +eitherTryFrom :: Exception.Exception exception => (source -> Either exception target) -> source -> Either (TryFromException.TryFromException source target) target -eitherTryCast f s = case f s of +eitherTryFrom f s = case f s of Left e -> Left . TryFromException.TryFromException s . Just $ Exception.toException e Right t -> Right t @@ -164,27 +164,7 @@ eitherTryCast f s = case f s of -- > either throw id . from -- > -- > -- Prefer this: --- > unsafeCast -unsafeCast - :: forall source target - . ( Stack.HasCallStack - , TryFrom.TryFrom source target - , Show source - , Typeable.Typeable source - , Typeable.Typeable target - ) - => source - -> target -unsafeCast = either Exception.throw id . TryFrom.tryFrom - --- | This function is like 'from' except that it will throw an impure --- exception if the conversion fails. --- --- > -- Avoid this: --- > either throw id . from @s --- > --- > -- Prefer this: --- > unsafeFrom @s +-- > unsafeFrom unsafeFrom :: forall source target . ( Stack.HasCallStack @@ -195,7 +175,7 @@ unsafeFrom ) => source -> target -unsafeFrom = unsafeCast +unsafeFrom = either Exception.throw id . TryFrom.tryFrom -- | This function is like 'into' except that it will throw an impure -- exception if the conversion fails. @@ -215,4 +195,4 @@ unsafeInto ) => source -> target -unsafeInto = unsafeCast +unsafeInto = unsafeFrom diff --git a/src/test/Main.hs b/src/test/Main.hs index b20817c..c9b4abd 100644 --- a/src/test/Main.hs +++ b/src/test/Main.hs @@ -62,23 +62,17 @@ main = Hspec.hspec . Hspec.describe "Witch" $ do Hspec.describe "tryInto" $ do test $ hush (Witch.tryInto @Int.Int8 (1 :: Int.Int16)) `Hspec.shouldBe` Just 1 - Hspec.describe "unsafeCast" $ do - test $ Witch.unsafeCast (1 :: Int.Int16) `Hspec.shouldBe` (1 :: Int.Int8) - test $ Exception.evaluate (Witch.unsafeCast @Int.Int16 @Int.Int8 128) `Hspec.shouldThrow` Hspec.anyException - Hspec.describe "unsafeFrom" $ do - test $ Witch.unsafeFrom @Int.Int16 1 `Hspec.shouldBe` (1 :: Int.Int8) + test $ Witch.unsafeFrom (1 :: Int.Int16) `Hspec.shouldBe` (1 :: Int.Int8) + test $ Exception.evaluate (Witch.unsafeFrom @Int.Int16 @Int.Int8 128) `Hspec.shouldThrow` Hspec.anyException Hspec.describe "unsafeInto" $ do test $ Witch.unsafeInto @Int.Int8 (1 :: Int.Int16) `Hspec.shouldBe` 1 Hspec.describe "Lift" $ do - Hspec.describe "liftedCast" $ do - test $ ($$(Witch.liftedCast (1 :: Int.Int16)) :: Int.Int8) `Hspec.shouldBe` 1 - Hspec.describe "liftedFrom" $ do - test $ ($$(Witch.liftedFrom @Int.Int16 1) :: Int.Int8) `Hspec.shouldBe` 1 + test $ ($$(Witch.liftedFrom (1 :: Int.Int16)) :: Int.Int8) `Hspec.shouldBe` 1 Hspec.describe "liftedInto" $ do test $ $$(Witch.liftedInto @Int.Int8 (1 :: Int.Int16)) `Hspec.shouldBe` 1