Replace "cast" functions with "from"

This commit is contained in:
Taylor Fausak 2021-05-10 21:04:51 -04:00
parent 1b55654c86
commit cdd86e9e2f
8 changed files with 142 additions and 231 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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