-- 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.6.1 module Strongweak.Util.Text tshow :: Show a => a -> Text module Strongweak.Util.Typeable typeRep' :: forall a. Typeable a => TypeRep 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 Weak a :: Type; } -- | Weaken some a to its associated weak type Weaken -- a. weaken :: Weaken a => a -> Weak a -- | Lift a function on a weak type to the associated strong type by -- weakening first. liftWeakF :: Weaken a => (Weak a -> b) -> a -> b -- | Strength enumeration: is it 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 :: Type
-- | Track multiple levels of weakening. Silly thought I had, don't think
-- it's useful.
type family SWDepth (n :: Natural) a :: Type
instance forall k (p :: k) a. Strongweak.Weaken.Weaken (Refined.Unsafe.Type.Refined p a)
instance forall k1 k (p :: k1) (f :: k -> GHC.Types.Type) (a :: k). Strongweak.Weaken.Weaken (Refined.Unsafe.Type.Refined1 p f a)
instance Strongweak.Weaken.Weaken (GHC.Base.NonEmpty a)
instance Data.Vector.Generic.Base.Vector v a => Strongweak.Weaken.Weaken (Data.Vector.Generic.Sized.Internal.Vector v n a)
instance Strongweak.Weaken.Weaken (Data.Functor.Identity.Identity a)
instance forall k a (b :: k). Strongweak.Weaken.Weaken (Data.Functor.Const.Const a b)
instance Strongweak.Weaken.Weaken GHC.Word.Word8
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.Int.Int8
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 a => Strongweak.Weaken.Weaken [a]
instance (Strongweak.Weaken.Weaken a, Strongweak.Weaken.Weaken b) => Strongweak.Weaken.Weaken (a, b)
instance (Strongweak.Weaken.Weaken a, Strongweak.Weaken.Weaken b) => Strongweak.Weaken.Weaken (Data.Either.Either a b)
module Strongweak.Strengthen.Unsafe
-- | Unsafely transform a Weaken 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] -- Failure ... --restrengthen :: (Strengthen a, Weaken a) => a -> Result a type Result = Validation Fails -- | Strengthen one numeric type into another. -- -- n must be "wider" than m. strengthenBounded :: forall m n. (Typeable n, Integral n, Show n, Typeable m, Integral m, Show m, Bounded m) => n -> Result m type Fails = NeAcc Fail -- | A failure encountered during strengthening. data Fail -- | A failure containing lots of detail. Use in concrete instances where -- you already have the Shows and Typeables needed. FailShow :: TypeRep -> TypeRep -> Maybe Text -> [Text] -> Fail -- | A failure. Use in abstract instances to avoid heavy contexts. -- (Remember that generic strengtheners should wrap these nicely anyway!) FailOther :: [Text] -> Fail -- | Some failures occurred when strengthening from one data type to -- another. -- -- Field indices are from 0 in the respective constructor. Field names -- are provided if are present in the type. -- -- This is primarily intended to be used by generic strengtheners. FailField :: String -> String -> String -> String -> Natural -> Maybe String -> Natural -> Maybe String -> Fails -> Fail prettyFail :: Fail -> Text fail1 :: Fail -> Result a failOther :: [Text] -> Result a failShow :: forall s w. (Typeable w, Show w, Typeable s) => w -> [Text] -> Result s -- | Succeed on Just, fail with given detail on Nothing. maybeFailShow :: forall a. (Typeable (Weak a), Typeable a) => [Text] -> Maybe a -> Result a -- | The weakened type for some type. type Weak a :: Type instance forall k (p :: k) a. (Refined.Predicate p a, Data.Typeable.Internal.Typeable a) => Strongweak.Strengthen.Strengthen (Refined.Unsafe.Type.Refined p a) instance forall k1 (p :: k1) ak (f :: ak -> GHC.Types.Type) (a :: ak). (Refined.Predicate1 p f, Data.Typeable.Internal.Typeable f, Data.Typeable.Internal.Typeable a, Data.Typeable.Internal.Typeable ak) => Strongweak.Strengthen.Strengthen (Refined.Unsafe.Type.Refined1 p f a) instance Data.Typeable.Internal.Typeable a => Strongweak.Strengthen.Strengthen (GHC.Base.NonEmpty a) instance (Data.Vector.Generic.Base.Vector v a, GHC.TypeNats.KnownNat n, Data.Typeable.Internal.Typeable v, Data.Typeable.Internal.Typeable a) => Strongweak.Strengthen.Strengthen (Data.Vector.Generic.Sized.Internal.Vector v n a) instance Strongweak.Strengthen.Strengthen (Data.Functor.Identity.Identity a) instance forall k a (b :: k). Strongweak.Strengthen.Strengthen (Data.Functor.Const.Const a b) instance Strongweak.Strengthen.Strengthen GHC.Word.Word8 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.Int.Int8 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 a => Strongweak.Strengthen.Strengthen [a] instance (Strongweak.Strengthen.Strengthen a, Strongweak.Strengthen.Strengthen b) => Strongweak.Strengthen.Strengthen (a, b) instance (Strongweak.Strengthen.Strengthen a, Strongweak.Strengthen.Strengthen b) => Strongweak.Strengthen.Strengthen (Data.Either.Either a b) instance GHC.Show.Show Strongweak.Strengthen.Fail instance Prettyprinter.Internal.Pretty Strongweak.Strengthen.Fail -- | strengthen over generic representations. -- -- Strengthen failures are annotated with precise information describing -- where the failure occurred: datatype name, constructor name, field -- index (and name if present). To achieve this, we split the generic -- derivation into 3 classes, each handling/"unwrapping" a different -- layer of the generic representation: datatype (D), constructor (C) and -- selector (S). module Strongweak.Generic.Strengthen -- | 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 -> Result s -- | Generic strengthening at the datatype level. class GStrengthenD w s gstrengthenD :: GStrengthenD w s => w p -> Result (s p) -- | Generic strengthening at the constructor sum level. class GStrengthenC wcd scd w s gstrengthenC :: GStrengthenC wcd scd w s => w p -> Result (s p) -- | Generic strengthening at the constructor level. class GStrengthenS wcd scd wcc scc (si :: Natural) w s gstrengthenS :: GStrengthenS wcd scd wcc scc si w s => w p -> Result (s p) (.>) :: (a -> b) -> (b -> c) -> a -> c -- | Get the record name for a selector if present. -- -- On the type level, a 'Maybe Symbol' is stored for record names. But -- the reification is done using fromMaybe "". So we have to -- inspect the resulting string to determine whether the field uses -- record syntax or not. (Silly.) selName'' :: forall s. Selector s => Maybe String -- | conName without the value (only used as a proxy). Lets us push -- our undefineds into one place. conName' :: forall c. Constructor c => String -- | datatypeName without the value (only used as a proxy). Lets us -- push our undefineds into one place. datatypeName' :: forall d. Datatype d => String -- | selName without the value (only used as a proxy). Lets us push -- our undefineds into one place. selName' :: forall s. Selector s => String type family ProdArity (f :: Type -> Type) :: Natural natVal'' :: forall n. KnownNat n => Natural instance forall k1 k2 k3 k4 (wcd :: k1) (scd :: k2) (wcc :: k3) (scc :: k4) (si :: GHC.Num.Natural.Natural) (wl :: GHC.Types.Type -> GHC.Types.Type) (sl :: GHC.Types.Type -> GHC.Types.Type) (wr :: GHC.Types.Type -> GHC.Types.Type) (sr :: GHC.Types.Type -> GHC.Types.Type). (Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc si wl sl, Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc (si GHC.TypeNats.+ Strongweak.Generic.Strengthen.ProdArity wl) wr sr) => Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc si (wl GHC.Generics.:*: wr) (sl GHC.Generics.:*: sr) instance forall k1 k2 k3 (wcd :: k1) (scd :: k2) (wcc :: GHC.Generics.Meta) (scc :: GHC.Generics.Meta) (w :: k3 -> GHC.Types.Type) (s :: k3 -> GHC.Types.Type). Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc 0 w s => Strongweak.Generic.Strengthen.GStrengthenC wcd scd (GHC.Generics.C1 wcc w) (GHC.Generics.C1 scc s) instance forall k1 k2 k3 k4 k5 (wcd :: k1) (scd :: k2) (wcc :: k3) (scc :: k4) (si :: GHC.Num.Natural.Natural). Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc si GHC.Generics.U1 GHC.Generics.U1 instance forall k1 k2 k3 k4 k5 (wcd :: k1) (scd :: k2) (wcc :: k3) (scc :: k4) (si :: GHC.Num.Natural.Natural) (wcs :: GHC.Generics.Meta) a (scs :: GHC.Generics.Meta). Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc si (GHC.Generics.S1 wcs (GHC.Generics.Rec0 a)) (GHC.Generics.S1 scs (GHC.Generics.Rec0 a)) instance forall k1 k2 k3 k4 k5 s w (wcd :: k1) (scd :: k2) (wcc :: k3) (scc :: k4) (wcs :: GHC.Generics.Meta) (scs :: GHC.Generics.Meta) (si :: GHC.TypeNats.Nat). (Strongweak.Weaken.Weak s GHC.Types.~ w, Strongweak.Strengthen.Strengthen s, GHC.Generics.Datatype wcd, GHC.Generics.Datatype scd, GHC.Generics.Constructor wcc, GHC.Generics.Constructor scc, GHC.Generics.Selector wcs, GHC.Generics.Selector scs, GHC.TypeNats.KnownNat si) => Strongweak.Generic.Strengthen.GStrengthenS wcd scd wcc scc si (GHC.Generics.S1 wcs (GHC.Generics.Rec0 w)) (GHC.Generics.S1 scs (GHC.Generics.Rec0 s)) instance forall k (wcd :: GHC.Generics.Meta) (scd :: GHC.Generics.Meta) (w :: k -> GHC.Types.Type) (s :: k -> GHC.Types.Type). Strongweak.Generic.Strengthen.GStrengthenC wcd scd w s => Strongweak.Generic.Strengthen.GStrengthenD (GHC.Generics.D1 wcd w) (GHC.Generics.D1 scd s) instance forall k1 k2 k3 (wcd :: k1) (scd :: k2). Strongweak.Generic.Strengthen.GStrengthenC wcd scd GHC.Generics.V1 GHC.Generics.V1 instance forall k1 k2 k3 (wcd :: k1) (scd :: k2) (wl :: k3 -> GHC.Types.Type) (sl :: k3 -> GHC.Types.Type) (wr :: k3 -> GHC.Types.Type) (sr :: k3 -> GHC.Types.Type). (Strongweak.Generic.Strengthen.GStrengthenC wcd scd wl sl, Strongweak.Generic.Strengthen.GStrengthenC wcd scd wr sr) => Strongweak.Generic.Strengthen.GStrengthenC wcd scd (wl GHC.Generics.:+: wr) (sl GHC.Generics.:+: sr) -- | weaken over generic representations. module Strongweak.Generic.Weaken -- | 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 class GWeaken s w gweaken :: GWeaken s w => s p -> w p instance forall k (s :: k -> GHC.Types.Type) (w :: k -> GHC.Types.Type) is (ms :: GHC.Generics.Meta) iw (mw :: GHC.Generics.Meta). Strongweak.Generic.Weaken.GWeaken s w => Strongweak.Generic.Weaken.GWeaken (GHC.Generics.M1 is ms s) (GHC.Generics.M1 iw mw w) instance Strongweak.Generic.Weaken.GWeaken GHC.Generics.V1 GHC.Generics.V1 instance Strongweak.Generic.Weaken.GWeaken GHC.Generics.U1 GHC.Generics.U1 instance Strongweak.Generic.Weaken.GWeaken (GHC.Generics.Rec0 s) (GHC.Generics.Rec0 s) instance (Strongweak.Weaken.Weaken s, Strongweak.Weaken.Weak s GHC.Types.~ w) => Strongweak.Generic.Weaken.GWeaken (GHC.Generics.Rec0 s) (GHC.Generics.Rec0 w) instance forall k (ls :: k -> GHC.Types.Type) (lw :: k -> GHC.Types.Type) (rs :: k -> GHC.Types.Type) (rw :: k -> GHC.Types.Type). (Strongweak.Generic.Weaken.GWeaken ls lw, Strongweak.Generic.Weaken.GWeaken rs rw) => Strongweak.Generic.Weaken.GWeaken (ls GHC.Generics.:*: rs) (lw GHC.Generics.:*: rw) instance forall k (ls :: k -> GHC.Types.Type) (lw :: k -> GHC.Types.Type) (rs :: k -> GHC.Types.Type) (rw :: k -> GHC.Types.Type). (Strongweak.Generic.Weaken.GWeaken ls lw, Strongweak.Generic.Weaken.GWeaken rs rw) => Strongweak.Generic.Weaken.GWeaken (ls GHC.Generics.:+: rs) (lw GHC.Generics.:+: rw) -- | 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 Weak a :: Type; } -- | Weaken some a to its associated weak type Weaken -- a. weaken :: Weaken a => a -> Weak a -- | Attempt to strengthen some Weak 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 Weak a to its associated -- strong type a. strengthen :: Strengthen a => Weak a -> Result a -- | Lift a function on a weak type to the associated strong type by -- weakening first. liftWeakF :: Weaken a => (Weak a -> b) -> a -> b -- | Strength enumeration: is it 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 :: Type
module Strongweak.Generic.Via
-- | 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)
--
--
-- TODO can't figure out a way around multiple standalone deriving
-- declarations :(
newtype GenericallySW s (w :: Type)
GenericallySW :: s -> GenericallySW s (w :: Type)
[unGenericallySW] :: GenericallySW s (w :: Type) -> s
instance (GHC.Generics.Generic s, GHC.Generics.Generic w, Strongweak.Generic.Weaken.GWeaken (GHC.Generics.Rep s) (GHC.Generics.Rep w)) => Strongweak.Weaken.Weaken (Strongweak.Generic.Via.GenericallySW s w)
instance (GHC.Generics.Generic s, GHC.Generics.Generic w, Strongweak.Generic.Strengthen.GStrengthenD (GHC.Generics.Rep w) (GHC.Generics.Rep s), Strongweak.Weaken.Weaken (Strongweak.Generic.Via.GenericallySW s w)) => Strongweak.Strengthen.Strengthen (Strongweak.Generic.Via.GenericallySW s w)
-- | 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 -> Result 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)
--
--
-- TODO can't figure out a way around multiple standalone deriving
-- declarations :(
newtype GenericallySW s (w :: Type)
GenericallySW :: s -> GenericallySW s (w :: Type)
[unGenericallySW] :: GenericallySW s (w :: Type) -> s