-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Convert between strong and weak representations of types -- -- Please see README.md. @package strongweak @version 0.11.0 module Strongweak.Util.TypeNats natVal'' :: forall (n :: Nat). KnownNat n => Natural module Strongweak.Weaken -- | Weaken some a, relaxing certain invariants. -- -- See Strongweak for class design notes and laws. class Weaken a where { -- | The weakened type for some type. type Weakened a; } -- | Weaken some a to its associated weak type Weakened -- a. weaken :: Weaken a => a -> Weakened a -- | The type of a after weakening n times. type family WeakenedN (n :: Natural) a -- | Lift a function on a weak type to the associated strong type by -- weakening first. liftWeakF :: Weaken a => (Weakened a -> b) -> a -> b -- | A "via type" newtype for defining strongweak instances for -- zero-invariant, coercible newtypes. -- -- Use like so: -- --
-- deriving via SWCoercibly a instance Weaken (Identity a) --newtype SWCoercibly a SWCoercibly :: a -> SWCoercibly a [unSWCoercibly] :: SWCoercibly a -> a instance forall k (b :: k) a. Strongweak.Weaken.Weaken (Data.Functor.Const.Const a b) instance (Strongweak.Weaken.Weaken a, Strongweak.Weaken.Weaken b) => Strongweak.Weaken.Weaken (Data.Either.Either a b) instance Strongweak.Weaken.Weaken (Data.Functor.Identity.Identity a) instance Strongweak.Weaken.Weaken GHC.Int.Int16 instance Strongweak.Weaken.Weaken GHC.Int.Int32 instance Strongweak.Weaken.Weaken GHC.Int.Int64 instance Strongweak.Weaken.Weaken GHC.Int.Int8 instance Strongweak.Weaken.Weaken a => Strongweak.Weaken.Weaken [a] instance Strongweak.Weaken.Weaken (GHC.Base.NonEmpty a) instance forall k (p :: k) a. Strongweak.Weaken.Weaken (Rerefined.Refine.Refined p a) instance forall k k1 (p :: k) (f :: k1 -> GHC.Types.Type) (a :: k1). Strongweak.Weaken.Weaken (Rerefined.Refine.Refined1 p f a) instance Strongweak.Weaken.Weaken (Strongweak.Weaken.SWCoercibly a) instance (Strongweak.Weaken.Weaken a, Strongweak.Weaken.Weaken b) => Strongweak.Weaken.Weaken (a, b) instance Data.Vector.Generic.Base.Vector v a => Strongweak.Weaken.Weaken (Data.Vector.Generic.Sized.Internal.Vector v n a) instance Strongweak.Weaken.Weaken GHC.Word.Word16 instance Strongweak.Weaken.Weaken GHC.Word.Word32 instance Strongweak.Weaken.Weaken GHC.Word.Word64 instance Strongweak.Weaken.Weaken GHC.Word.Word8 module Strongweak.Strengthen.Unsafe -- | Unsafely transform a Weakened a to an a, -- without asserting invariants. -- -- Naturally, you must only even consider using this if you have a -- guarantee that your value is safe to treat as strong. -- -- For example, you may unsafely strengthen some Natural -- n into a Word8 by unsafely coercing the value, ignoring -- the possibility that n >= 255. -- -- What happens if it turns out you're lying to the computer and your -- weak value doesn't fit in its strong counterpart? That depends on the -- strengthen. -- --
-- >>> restrengthen $ unsafeStrengthen @(Vector 2 Natural) [0] -- Left ... --restrengthen :: (Strengthen a, Weaken a) => a -> Either StrengthenFailure' a -- | Strengthen one numeric type into another. -- -- n must be "wider" than m. -- -- FiniteBits m is for error printing. strengthenBounded :: forall m n. (Typeable n, Integral n, Typeable m, Integral m, Bounded m, FiniteBits m) => n -> Either StrengthenFailure' m -- | A failure encountered during strengthening. -- -- Strengthening can involve multiple distinct checks. In such cases, you -- may record multiple failures in a single StrengthenFailure by -- placing them in the inner failure list and noting their meaning in the -- detail field. data StrengthenFailure text StrengthenFailure :: [text] -> [(text, StrengthenFailure text)] -> StrengthenFailure text -- | Detail on strengthen failure. -- -- We use a list here for the cases where you want multiple lines of -- detail. Separating with a newline would make prettifying later harder, -- so we delay. -- -- Note that this should probably never be empty. TODO consider -- NonEmpty, but fairly unimportant. [strengthenFailDetail] :: StrengthenFailure text -> [text] -- | Optional wrapped failures. -- -- The text type acts as an index. Its meaning depends on the -- failure in question, and should be explained in -- strengthenFailDetail. [strengthenFailInner] :: StrengthenFailure text -> [(text, StrengthenFailure text)] type StrengthenFailure' = StrengthenFailure Builder -- | Shorthand for failing a strengthen with no inner failures. failStrengthen1 :: [text] -> Either (StrengthenFailure text) a -- | Shorthand for failing a strengthen. failStrengthen :: [text] -> [(text, StrengthenFailure text)] -> Either (StrengthenFailure text) a -- | The weakened type for some type. type family Weakened a instance GHC.Show.Show text => GHC.Show.Show (Strongweak.Strengthen.StrengthenFailure text) instance forall k (b :: k) a. Strongweak.Strengthen.Strengthen (Data.Functor.Const.Const a b) instance (Strongweak.Strengthen.Strengthen a, Strongweak.Strengthen.Strengthen b) => Strongweak.Strengthen.Strengthen (Data.Either.Either a b) instance Strongweak.Strengthen.Strengthen (Data.Functor.Identity.Identity a) instance Strongweak.Strengthen.Strengthen GHC.Int.Int16 instance Strongweak.Strengthen.Strengthen GHC.Int.Int32 instance Strongweak.Strengthen.Strengthen GHC.Int.Int64 instance Strongweak.Strengthen.Strengthen GHC.Int.Int8 instance Strongweak.Strengthen.Strengthen a => Strongweak.Strengthen.Strengthen [a] instance Strongweak.Strengthen.Strengthen (GHC.Base.NonEmpty a) instance forall k (p :: k) a. Rerefined.Predicate.Refine p a => Strongweak.Strengthen.Strengthen (Rerefined.Refine.Refined p a) instance forall k k1 (p :: k) (f :: k1 -> GHC.Types.Type) (a :: k1). Rerefined.Predicate.Refine1 p f => Strongweak.Strengthen.Strengthen (Rerefined.Refine.Refined1 p f a) instance Strongweak.Strengthen.Strengthen (Strongweak.Weaken.SWCoercibly a) instance (Strongweak.Strengthen.Strengthen l, Strongweak.Strengthen.Strengthen r) => Strongweak.Strengthen.Strengthen (l, r) instance (Data.Vector.Generic.Base.Vector v a, GHC.TypeNats.KnownNat n) => Strongweak.Strengthen.Strengthen (Data.Vector.Generic.Sized.Internal.Vector v n a) instance Strongweak.Strengthen.Strengthen GHC.Word.Word16 instance Strongweak.Strengthen.Strengthen GHC.Word.Word32 instance Strongweak.Strengthen.Strengthen GHC.Word.Word64 instance Strongweak.Strengthen.Strengthen GHC.Word.Word8 -- | strengthen over generic representations. -- -- As with base instances, generic strengthening collates all failures -- rather than short-circuiting on the first failure. Failures are -- annotated with precise information describing where the failure -- occurred: -- --
-- Weakened (WeakenN 0 a) = a -- Weakened (WeakenN 1 a) = Weakened a -- Weakened (WeakenN 2 a) = Weakened (Weakened a) -- Weakened (WeakenN n a) = WeakenedN n a ---- -- And so on. (This type is only much use from n = 2 onwards.) newtype WeakenN (n :: Natural) a WeakenN :: a -> WeakenN (n :: Natural) a [unWeakenN] :: WeakenN (n :: Natural) a -> a instance GHC.Classes.Eq a => GHC.Classes.Eq (Strongweak.WeakenN.WeakenN n a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Strongweak.WeakenN.WeakenN n a) instance GHC.Show.Show a => GHC.Show.Show (Strongweak.WeakenN.WeakenN n a) instance Strongweak.WeakenN.Internal.StrengthenWeakenN n a => Strongweak.Strengthen.Strengthen (Strongweak.WeakenN.WeakenN n a) instance Strongweak.WeakenN.Internal.WeakenWeakenN n a => Strongweak.Weaken.Weaken (Strongweak.WeakenN.WeakenN n a) -- | Definitions using a type-level strength switch. module Strongweak.Strength -- | Strength enumeration: it's either strong, or weak. -- -- Primarily interesting at the type level (using DataKinds). data Strength Strong :: Strength Weak :: Strength -- | Get either the strong or weak representation of a type, depending on -- the type-level "switch" provided. -- -- This is intended to be used in data types that take a Strength -- type. Define your type using strong fields wrapped in SW s. -- You then get the weak representation for free, using the same -- definition. -- --
-- data A (s :: Strength) = A
-- { a1 :: SW s Word8
-- , a2 :: String }
--
type family SW (s :: Strength) a
-- | Shortcut for a SW-wrapped WeakenN.
type SWN (s :: Strength) (n :: Natural) a = SW s WeakenN n a
-- | Generic strengthen and weaken.
module Strongweak.Generic
-- | Weaken a value generically.
--
-- The weak and strong types must be compatible. See
-- Generic for the definition of compatibility in this context.
weakenGeneric :: (Generic s, Generic w, GWeaken (Rep s) (Rep w)) => s -> w
-- | Strengthen a value generically.
--
-- The weak and strong types must be compatible. See
-- Generic for the definition of compatibility in this context.
strengthenGeneric :: (Generic w, Generic s, GStrengthenD (Rep w) (Rep s)) => w -> Either StrengthenFailure' s
-- | DerivingVia wrapper for strongweak instances.
--
-- We can't use Generically conveniently because we need to talk
-- about two data types, not one -- we would have to do something like
-- Generically (Tagged w s), which is ugly. So
-- we instead define our own adorable little "via type" here!
--
-- Use like so:
--
--
-- data XYZ (s :: Strength) = XYZ
-- { xyz1 :: SW s Word8
-- , xyz2 :: Word8
-- , xyz3 :: ()
-- } deriving stock Generic
-- deriving via (GenericallySW (XYZ 'Strong) (XYZ 'Weak)) instance Weaken (XYZ 'Strong)
-- deriving via (GenericallySW (XYZ 'Strong) (XYZ 'Weak)) instance Strengthen (XYZ 'Strong)
--
--
-- Regrettably, use of this requires UndecidableInstances.
newtype GenericallySW s w
GenericallySW :: s -> GenericallySW s w
[unGenericallySW] :: GenericallySW s w -> s
-- | GenericallySW where the type takes a Strength in its
-- last type var.
--
-- Shorter instances for types of a certain shape.
--
-- Regrettably, use of this requires UndecidableInstances.
newtype GenericallySW0 (f :: Strength -> Type)
GenericallySW0 :: f 'Strong -> GenericallySW0 (f :: Strength -> Type)
[unGenericallySW0] :: GenericallySW0 (f :: Strength -> Type) -> f 'Strong
instance (GHC.Generics.Generic s, GHC.Generics.Generic w, Strongweak.Strengthen.Generic.GStrengthenD (GHC.Generics.Rep w) (GHC.Generics.Rep s), Strongweak.Weaken.Weaken (Strongweak.Generic.GenericallySW s w)) => Strongweak.Strengthen.Strengthen (Strongweak.Generic.GenericallySW s w)
instance (GHC.Generics.Generic (f 'Strongweak.Strength.Strong), GHC.Generics.Generic (f 'Strongweak.Strength.Weak), Strongweak.Strengthen.Generic.GStrengthenD (GHC.Generics.Rep (f 'Strongweak.Strength.Weak)) (GHC.Generics.Rep (f 'Strongweak.Strength.Strong)), Strongweak.Weaken.Weaken (Strongweak.Generic.GenericallySW0 f)) => Strongweak.Strengthen.Strengthen (Strongweak.Generic.GenericallySW0 f)
instance (GHC.Generics.Generic s, GHC.Generics.Generic w, Strongweak.Weaken.Generic.GWeaken (GHC.Generics.Rep s) (GHC.Generics.Rep w)) => Strongweak.Weaken.Weaken (Strongweak.Generic.GenericallySW s w)
instance (GHC.Generics.Generic (f 'Strongweak.Strength.Strong), GHC.Generics.Generic (f 'Strongweak.Strength.Weak), Strongweak.Weaken.Generic.GWeaken (GHC.Generics.Rep (f 'Strongweak.Strength.Strong)) (GHC.Generics.Rep (f 'Strongweak.Strength.Weak))) => Strongweak.Weaken.Weaken (Strongweak.Generic.GenericallySW0 f)
-- | Main import module for basic use.
--
-- For defining Strengthen instances, import
-- Strongweak.Strengthen.
module Strongweak
-- | Weaken some a, relaxing certain invariants.
--
-- See Strongweak for class design notes and laws.
class Weaken a where {
-- | The weakened type for some type.
type Weakened a;
}
-- | Weaken some a to its associated weak type Weakened
-- a.
weaken :: Weaken a => a -> Weakened a
-- | Attempt to strengthen some Weakened a, asserting
-- certain invariants.
--
-- We take Weaken as a superclass in order to maintain strong/weak
-- type pair consistency. We choose this dependency direction because we
-- treat the strong type as the "canonical" one, so Weaken is the
-- more natural (and straightforward) class to define. That does mean the
-- instances for this class are a little confusingly worded. Alas.
--
-- See Strongweak for class design notes and laws.
class Weaken a => Strengthen a
-- | Attempt to strengthen some Weakened a to its
-- associated strong type a.
strengthen :: Strengthen a => Weakened a -> Either StrengthenFailure' a
-- | When weakening (or strengthening), chain the operation n
-- times.
--
-- You may achieve this without extra newtypes by nesting uses of
-- SW. However, strongweak generics can't handle this, forcing you
-- to write manual instances.
--
-- WeakenN provides this nesting behaviour in a type. In return
-- for adding a boring newtype layer to the strong representation, you
-- can chain weakening and strengthenings without having to write them
-- manually.
--
-- The type works as follows:
--
-- -- Weakened (WeakenN 0 a) = a -- Weakened (WeakenN 1 a) = Weakened a -- Weakened (WeakenN 2 a) = Weakened (Weakened a) -- Weakened (WeakenN n a) = WeakenedN n a ---- -- And so on. (This type is only much use from n = 2 onwards.) newtype WeakenN (n :: Natural) a WeakenN :: a -> WeakenN (n :: Natural) a [unWeakenN] :: WeakenN (n :: Natural) a -> a -- | A "via type" newtype for defining strongweak instances for -- zero-invariant, coercible newtypes. -- -- Use like so: -- --
-- deriving via SWCoercibly a instance Weaken (Identity a) --newtype SWCoercibly a SWCoercibly :: a -> SWCoercibly a [unSWCoercibly] :: SWCoercibly a -> a -- | Lift a function on a weak type to the associated strong type by -- weakening first. liftWeakF :: Weaken a => (Weakened a -> b) -> a -> b -- | Strength enumeration: it's either strong, or weak. -- -- Primarily interesting at the type level (using DataKinds). data Strength Strong :: Strength Weak :: Strength -- | Get either the strong or weak representation of a type, depending on -- the type-level "switch" provided. -- -- This is intended to be used in data types that take a Strength -- type. Define your type using strong fields wrapped in SW s. -- You then get the weak representation for free, using the same -- definition. -- --
-- data A (s :: Strength) = A
-- { a1 :: SW s Word8
-- , a2 :: String }
--
type family SW (s :: Strength) a
-- | Shortcut for a SW-wrapped WeakenN.
type SWN (s :: Strength) (n :: Natural) a = SW s WeakenN n a