-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Classes for working with types that can change clothes. -- -- Types that are parametric on a functor are like Barbies that have an -- outfit for each role. This package provides the basic abstractions to -- work with them comfortably. @package barbies @version 1.1.0.0 -- | Generalize the standard two-functor Product to the product of -- n-functors. Intuitively, this means: -- --
-- Product f g a ~~ (f a, g a) -- -- Prod '[] a ~~ Const () a -- Prod '[f] a ~~ (f a) -- Prod '[f, g] a ~~ (f a, g a) -- Prod '[f, g, h] a ~~ (f a, g a, h a) -- ⋮ --module Data.Functor.Prod -- | Product of n functors. data Prod :: [k -> Type] -> k -> Type [Unit] :: Prod '[] a [Cons] :: f a -> Prod fs a -> Prod (f : fs) a -- | The unit of the product. zeroTuple :: Prod '[] a -- | Lift a functor to a 1-tuple. oneTuple :: f a -> Prod '[f] a -- | Conversion from a standard Product fromProduct :: Product f g a -> Prod '[f, g] a -- | Conversion to a standard Product toProduct :: Prod '[f, g] a -> Product f g a -- | Flat product of products. prod :: Prod ls a -> Prod rs a -> Prod (ls ++ rs) a -- | Like uncurry but using Prod instead of pairs. Can be -- thought of as a family of functions: -- --
-- uncurryn :: r a -> Prod '[] a -- uncurryn :: (f a -> r a) -> Prod '[f] a -- uncurryn :: (f a -> g a -> r a) -> Prod '[f, g] a -- uncurryn :: (f a -> g a -> h a -> r a) -> Prod '[f, g, h] a -- ⋮ --uncurryn :: Curried (Prod fs a -> r a) -> Prod fs a -> r a -- | Type-level, poly-kinded, list-concatenation. type family (++) l r :: [k] -- | Prod '[f, g, h] a -> r is the type of the uncurried -- form of a function f a -> g a -> h a -> r. -- Curried moves from the former to the later. E.g. -- --
-- Curried (Prod '[] a -> r) = r a -- Curried (Prod '[f] a -> r) = f a -> r a -- Curried (Prod '[f, g] a -> r) = f a -> g a -> r a --type family Curried t instance GHC.Base.Functor (Data.Functor.Prod.Prod '[]) instance (GHC.Base.Functor f, GHC.Base.Functor (Data.Functor.Prod.Prod fs)) => GHC.Base.Functor (Data.Functor.Prod.Prod (f : fs)) instance GHC.Base.Applicative (Data.Functor.Prod.Prod '[]) instance (GHC.Base.Applicative f, GHC.Base.Applicative (Data.Functor.Prod.Prod fs)) => GHC.Base.Applicative (Data.Functor.Prod.Prod (f : fs)) instance GHC.Base.Alternative (Data.Functor.Prod.Prod '[]) instance (GHC.Base.Alternative f, GHC.Base.Alternative (Data.Functor.Prod.Prod fs)) => GHC.Base.Alternative (Data.Functor.Prod.Prod (f : fs)) instance Data.Foldable.Foldable (Data.Functor.Prod.Prod '[]) instance (Data.Foldable.Foldable f, Data.Foldable.Foldable (Data.Functor.Prod.Prod fs)) => Data.Foldable.Foldable (Data.Functor.Prod.Prod (f : fs)) instance Data.Traversable.Traversable (Data.Functor.Prod.Prod '[]) instance (Data.Traversable.Traversable f, Data.Traversable.Traversable (Data.Functor.Prod.Prod fs)) => Data.Traversable.Traversable (Data.Functor.Prod.Prod (f : fs)) instance Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod '[]) instance (Data.Functor.Classes.Eq1 f, Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod fs)) => Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod (f : fs)) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Functor.Prod.Prod '[] a) instance (Data.Functor.Classes.Eq1 f, GHC.Classes.Eq a, Data.Functor.Classes.Eq1 (Data.Functor.Prod.Prod fs)) => GHC.Classes.Eq (Data.Functor.Prod.Prod (f : fs) a) instance Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod '[]) instance (Data.Functor.Classes.Ord1 f, Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod fs)) => Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod (f : fs)) instance GHC.Classes.Ord a => GHC.Classes.Ord (Data.Functor.Prod.Prod '[] a) instance (Data.Functor.Classes.Ord1 f, GHC.Classes.Ord a, Data.Functor.Classes.Ord1 (Data.Functor.Prod.Prod fs)) => GHC.Classes.Ord (Data.Functor.Prod.Prod (f : fs) a) instance Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod '[]) instance (Data.Functor.Classes.Show1 f, Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod fs)) => Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod (f : fs)) instance GHC.Show.Show a => GHC.Show.Show (Data.Functor.Prod.Prod '[] a) instance (Data.Functor.Classes.Show1 f, GHC.Show.Show a, Data.Functor.Classes.Show1 (Data.Functor.Prod.Prod fs)) => GHC.Show.Show (Data.Functor.Prod.Prod (f : fs) a) -- | Support for operating on Barbie-types with constrained functions. -- -- Consider the following function: -- --
-- showIt :: Show a => Maybe a -> Const String a -- showIt = Const . show ---- -- We would then like to be able to do: -- --
-- bmap showIt :: FunctorB b => b Maybe -> b (Const String) ---- -- This however doesn't work because of the (Show a) -- constraint in the the type of showIt. -- -- This module adds support to overcome this problem. module Data.Barbie.Constraints -- | Dict c a is evidence that there exists an instance of -- c a. -- -- It is essentially equivalent to Dict (c a) from the -- constraints package, but because of its kind, it allows us to -- define things like Dict Show. data Dict c a [Dict] :: c a => Dict c a -- | Turn a constrained-function into an unconstrained one that uses the -- packed instance dictionary instead. requiringDict :: (c a => r) -> Dict c a -> r -- | Instances of this class provide means to talk about constraints, both -- at compile-time, using AllB, and at run-time, in the form of -- Dict, via baddDicts. -- -- A manual definition would look like this: -- --
-- data T f = A (f Int) (f String) | B (f Bool) (f Int) -- -- instance ConstraintsB T where -- type AllB c T = (c Int, c String, c Bool) -- -- baddDicts t = case t of -- A x y -> A (Pair Dict x) (Pair Dict y) -- B z w -> B (Pair Dict z) (Pair Dict w) ---- -- Now if we given a T f, we need to use the Show -- instance of their fields, we can use: -- --
-- baddDicts :: AllB Show b => b f -> b (Dict Show Product b) ---- -- There is a default implementation of ConstraintsB for -- Generic types, so in practice one will simply do: -- --
-- derive instance Generic (T f) -- instance ConstraintsB T --class FunctorB b => ConstraintsB (b :: (k -> *) -> *) where { -- | AllB c b should contain a constraint c a for -- each a occurring under an f in b f. E.g.: -- --
-- AllB Show Barbie ~ (Show String, Show Int)
--
--
-- For requiring constraints of the form c (f a), use
-- AllBF.
type family AllB (c :: k -> Constraint) b :: Constraint;
type AllB c b = GAllB c (GAllBRep b);
}
baddDicts :: forall c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f)
baddDicts :: forall c f. (ConstraintsB b, CanDeriveConstraintsB c b f, AllB c b) => b f -> b (Dict c `Product` f)
-- | Every type b that is an instance of both ProductB and
-- ConstraintsB can be made an instance of ProductBC as
-- well.
--
-- Intuitively, in addition to buniq from ProductB, one can
-- define buniqC that takes into account constraints:
--
-- -- buniq :: (forall a . f a) -> b f -- buniqC :: AllB c b => (forall a . c a => f a) -> b f ---- -- For technical reasons, buniqC is not currently provided as a -- method of this class and is instead defined in terms bdicts, -- which is similar to baddDicts but can produce the instance -- dictionaries out-of-the-blue. bdicts could also be defined in -- terms of buniqC, so they are essentially equivalent. -- --
-- bdicts :: forall c b . AllB c b => b (Dict c) -- bdicts = buniqC (Dict @c) ---- -- There is a default implementation for Generic types, so -- instances can derived automatically. class (ConstraintsB b, ProductB b) => ProductBC (b :: (k -> Type) -> Type) bdicts :: (ProductBC b, AllB c b) => b (Dict c) bdicts :: (ProductBC b, CanDeriveProductBC c b, AllB c b) => b (Dict c) -- | Similar to AllB but will put the functor argument f -- between the constraint c and the type a. For -- example: -- --
-- AllB Show Barbie ~ (Show String, Show Int) -- AllBF Show f Barbie ~ (Show (f String), Show (f Int)) -- --type AllBF c f b = AllB (ClassF c f) b -- | ClassF has one universal instance that makes ClassF -- c f a equivalent to c (f a). However, we have -- --
-- 'ClassF c f :: k -> Constraint ---- -- This is useful since it allows to define constraint-constructors like -- ClassF Monoid Maybe class c (f a) => ClassF c f a -- | Like ClassF but for binary relations. class c (f a) (g a) => ClassFG c f g a -- | Deprecated: Renamed to AllBF (now based on AllB) type ConstraintsOf c f b = AllBF c f b -- | Deprecated: Renamed to baddDicts adjProof :: forall b c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f) -- | Deprecated: Class was renamed to ProductBC type ProofB b = ProductBC b -- | Sometimes one needs a type like Barbie Identity and it -- may feel like a second-class record type, where one needs to unpack -- values in each field. For those cases, we can leverage on closed -- type-families: -- --
-- data Bare
-- data Covered
--
-- type family Wear t f a where
-- Wear Bare f a = a
-- Wear Covered f a = f a
--
-- data SignUpForm t f
-- = SignUpForm'
-- { username :: Wear t f String,
-- , password :: Wear t f String
-- , mailingOk :: Wear t f Bool
-- }
-- instance FunctorB (SignUpForm Covered)
-- instance TraversableB (SignUpForm Covered)
-- ...,
-- instance BareB SignUpForm
--
-- type SignUpRaw = SignUpForm Maybe
-- type SignUpData = SignUpForm Bare
--
-- formData = SignUpForm "jbond" "shaken007" False :: SignUpData
--
module Data.Barbie.Bare
-- | The Wear type-function allows one to define a Barbie-type as
--
--
-- data B t f
-- = B { f1 :: Wear t f Int
-- , f2 :: Wear t f Bool
-- }
--
--
-- This gives rise to two rather different types:
--
--
-- B { f1 :: 5, f2 = True } :: B Bare f
--
type family Wear t f a
data Bare
data Covered
-- | Class of Barbie-types defined using Wear and can therefore have
-- Bare versions. Must satisfy:
--
-- -- bcover . bstrip = id -- bstrip . bcover = id --class FunctorB (b Covered) => BareB b bstrip :: BareB b => b Covered Identity -> b Bare Identity bcover :: BareB b => b Bare Identity -> b Covered Identity bstrip :: (BareB b, CanDeriveBareB b) => b Covered Identity -> b Bare Identity bcover :: (BareB b, CanDeriveBareB b) => b Bare Identity -> b Covered Identity -- | Generalization of bstrip to arbitrary functors bstripFrom :: BareB b => (forall a. f a -> a) -> b Covered f -> b Bare Identity -- | Generalization of bcover to arbitrary functors bcoverWith :: BareB b => (forall a. a -> f a) -> b Bare Identity -> b Covered f module Data.Barbie.Internal -- | Default implementation of bmap based on Generic. gbmapDefault :: CanDeriveFunctorB b f g => (forall a. f a -> g a) -> b f -> b g class GFunctorB f g repbf repbg gbmap :: GFunctorB f g repbf repbg => (forall a. f a -> g a) -> repbf x -> repbg x -- | CanDeriveFunctorB B f g is in practice a predicate -- about B only. Intuitively, it says that the following holds, -- for any arbitrary f: -- --
-- data Barbie f
-- = Barbie
-- { name :: f String
-- , age :: f Int
-- }
--
-- b1 :: Barbie Last -- Barbie with a monoid structure
-- b2 :: Barbie (Const a) -- Container Barbie
-- b3 :: Barbie Identity -- Barbie's new clothes
--
--
-- This module define the classes to work with these types and easily
-- transform them. They all come with default instances based on
-- Generic, so using them is as easy as:
--
--
-- data Barbie f
-- = Barbie
-- { name :: f String
-- , age :: f Int
-- }
-- deriving
-- ( Generic
-- , FunctorB, TraversableB, ProductB, ConstraintsB, ProductBC
-- )
--
-- deriving instance AllBF Show f Barbie => Show (Barbie f)
-- deriving instance AllBF Eq f Barbie => Eq (Barbie f)
--
--
-- Sometimes one wants to use Barbie Identity and it may
-- feel like a second-class record type, where one needs to unpack values
-- in each field. Data.Barbie.Bare offers a way to have bare
-- versions of a barbie-type.
--
-- Notice that all classes in this package are poly-kinded. Intuitively,
-- a barbie is a type parameterised by a functor, and because a barbies
-- is a type of functor, a type parameterised by a barbie is a
-- (higher-kinded) barbie too:
--
-- -- data Catalog b -- = Catalog (b Identity) (b Maybe) -- deriving -- (Generic -- , FunctorB, TraversableB, ProductB, ConstraintsB, ProductBC -- ) --module Data.Barbie -- | Barbie-types that can be mapped over. Instances of FunctorB -- should satisfy the following laws: -- --
-- bmap id = id -- bmap f . bmap g = bmap (f . g) ---- -- There is a default bmap implementation for Generic -- types, so instances can derived automatically. class FunctorB (b :: (k -> Type) -> Type) bmap :: FunctorB b => (forall a. f a -> g a) -> b f -> b g bmap :: forall f g. (FunctorB b, CanDeriveFunctorB b f g) => (forall a. f a -> g a) -> b f -> b g -- | Barbie-types that can be traversed from left to right. Instances -- should satisfy the following laws: -- --
-- t . btraverse f = btraverse (t . f) -- naturality -- btraverse Identity = Identity -- identity -- btraverse (Compose . fmap g . f) = Compose . fmap (btraverse g) . btraverse f -- composition ---- -- There is a default btraverse implementation for Generic -- types, so instances can derived automatically. class FunctorB b => TraversableB (b :: (k -> Type) -> Type) btraverse :: (TraversableB b, Applicative t) => (forall a. f a -> t (g a)) -> b f -> t (b g) btraverse :: (TraversableB b, Applicative t, CanDeriveTraversableB b f g) => (forall a. f a -> t (g a)) -> b f -> t (b g) -- | Map each element to an action, evaluate these actions from left to -- right, and ignore the results. btraverse_ :: (TraversableB b, Applicative t) => (forall a. f a -> t c) -> b f -> t () -- | Map each element to a monoid, and combine the results. bfoldMap :: (TraversableB b, Monoid m) => (forall a. f a -> m) -> b f -> m -- | Evaluate each action in the structure from left to right, and collect -- the results. bsequence :: (Applicative f, TraversableB b) => b (Compose f g) -> f (b g) -- | A version of bsequence with g specialized to -- Identity. bsequence' :: (Applicative f, TraversableB b) => b f -> f (b Identity) -- | Barbie-types that can form products, subject to the laws: -- --
-- bmap (\(Pair a _) -> a) . uncurry . bprod = fst -- bmap (\(Pair _ b) -> b) . uncurry . bprod = snd ---- -- Notice that because of the laws, having an internal product structure -- is not enough to have a lawful instance. E.g. -- --
-- data Ok f = Ok {o1 :: f String, o2 :: f Int}
-- data Bad f = Bad{b1 :: f String, hiddenFromArg: Int} -- no lawful instance
--
--
-- Intuitively, the laws for this class require that b hides no
-- structure from its argument f. Because of this, if we are
-- given any:
--
-- -- x :: forall a . f a ---- -- then this determines a unique value of type b f, witnessed by -- the buniq method. For example: -- --
-- buniq x = Ok {o1 = x, o2 = x}
--
--
-- Formally, buniq should satisfy:
--
-- -- const (buniq x) = bmap (const x) ---- -- There is a default implementation of bprod and buniq for -- Generic types, so instances can derived automatically. class FunctorB b => ProductB (b :: (k -> Type) -> Type) bprod :: ProductB b => b f -> b g -> b (f `Product` g) buniq :: ProductB b => (forall a. f a) -> b f bprod :: (ProductB b, CanDeriveProductB b f g) => b f -> b g -> b (f `Product` g) buniq :: (ProductB b, CanDeriveProductB b f f) => (forall a. f a) -> b f -- | An alias of bprod, since this is like a zip for -- Barbie-types. bzip :: ProductB b => b f -> b g -> b (f `Product` g) -- | An equivalent of unzip for Barbie-types. bunzip :: ProductB b => b (f `Product` g) -> (b f, b g) -- | An equivalent of zipWith for Barbie-types. bzipWith :: ProductB b => (forall a. f a -> g a -> h a) -> b f -> b g -> b h -- | An equivalent of zipWith3 for Barbie-types. bzipWith3 :: ProductB b => (forall a. f a -> g a -> h a -> i a) -> b f -> b g -> b h -> b i -- | An equivalent of zipWith4 for Barbie-types. bzipWith4 :: ProductB b => (forall a. f a -> g a -> h a -> i a -> j a) -> b f -> b g -> b h -> b i -> b j -- | Like bprod, but returns a binary Prod, instead of -- Product, which composes better. -- -- See /*/ for usage. (/*/) :: ProductB b => b f -> b g -> b (Prod '[f, g]) infixr 4 /*/ -- | Similar to /*/ but one of the sides is already a -- Prod fs. -- -- Note that /*, /*/ and uncurryn are meant to be -- used together: /* and /*/ combine b f1, b f2...b -- fn into a single product that can then be consumed by using -- uncurryn on an n-ary function. E.g. -- --
-- f :: f a -> g a -> h a -> i a -- -- bmap (uncurryn f) (bf /* bg /*/ bh) --(/*) :: ProductB b => b f -> b (Prod fs) -> b (Prod (f : fs)) infixr 4 /* -- | Instances of this class provide means to talk about constraints, both -- at compile-time, using AllB, and at run-time, in the form of -- Dict, via baddDicts. -- -- A manual definition would look like this: -- --
-- data T f = A (f Int) (f String) | B (f Bool) (f Int) -- -- instance ConstraintsB T where -- type AllB c T = (c Int, c String, c Bool) -- -- baddDicts t = case t of -- A x y -> A (Pair Dict x) (Pair Dict y) -- B z w -> B (Pair Dict z) (Pair Dict w) ---- -- Now if we given a T f, we need to use the Show -- instance of their fields, we can use: -- --
-- baddDicts :: AllB Show b => b f -> b (Dict Show Product b) ---- -- There is a default implementation of ConstraintsB for -- Generic types, so in practice one will simply do: -- --
-- derive instance Generic (T f) -- instance ConstraintsB T --class FunctorB b => ConstraintsB (b :: (k -> *) -> *) where { -- | AllB c b should contain a constraint c a for -- each a occurring under an f in b f. E.g.: -- --
-- AllB Show Barbie ~ (Show String, Show Int)
--
--
-- For requiring constraints of the form c (f a), use
-- AllBF.
type family AllB (c :: k -> Constraint) b :: Constraint;
type AllB c b = GAllB c (GAllBRep b);
}
baddDicts :: forall c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f)
baddDicts :: forall c f. (ConstraintsB b, CanDeriveConstraintsB c b f, AllB c b) => b f -> b (Dict c `Product` f)
-- | Similar to AllB but will put the functor argument f
-- between the constraint c and the type a. For
-- example:
--
-- -- AllB Show Barbie ~ (Show String, Show Int) -- AllBF Show f Barbie ~ (Show (f String), Show (f Int)) -- --type AllBF c f b = AllB (ClassF c f) b -- | Every type b that is an instance of both ProductB and -- ConstraintsB can be made an instance of ProductBC as -- well. -- -- Intuitively, in addition to buniq from ProductB, one can -- define buniqC that takes into account constraints: -- --
-- buniq :: (forall a . f a) -> b f -- buniqC :: AllB c b => (forall a . c a => f a) -> b f ---- -- For technical reasons, buniqC is not currently provided as a -- method of this class and is instead defined in terms bdicts, -- which is similar to baddDicts but can produce the instance -- dictionaries out-of-the-blue. bdicts could also be defined in -- terms of buniqC, so they are essentially equivalent. -- --
-- bdicts :: forall c b . AllB c b => b (Dict c) -- bdicts = buniqC (Dict @c) ---- -- There is a default implementation for Generic types, so -- instances can derived automatically. class (ConstraintsB b, ProductB b) => ProductBC (b :: (k -> Type) -> Type) bdicts :: (ProductBC b, AllB c b) => b (Dict c) bdicts :: (ProductBC b, CanDeriveProductBC c b, AllB c b) => b (Dict c) -- | Like buniq but a constraint is allowed to be required on each -- element of b. buniqC :: forall c f b. (AllB c b, ProductBC b) => (forall a. c a => f a) -> b f -- | Builds a b f, by applying mempty on every field of -- b. bmempty :: forall f b. (AllBF Monoid f b, ProductBC b) => b f -- | A wrapper for Barbie-types, providing useful instances. newtype Barbie (b :: (k -> Type) -> Type) f Barbie :: b f -> Barbie f [getBarbie] :: Barbie f -> b f -- | Uninhabited barbie type. data Void (f :: k -> Type) -- | A barbie type without structure. data Unit (f :: k -> Type) Unit :: Unit newtype Rec (p :: Type) a x Rec :: K1 R a x -> Rec a x [unRec] :: Rec a x -> K1 R a x -- | Deprecated: Renamed to AllBF (now based on AllB) type ConstraintsOf c f b = AllBF c f b -- | Deprecated: Renamed to baddDicts adjProof :: forall b c f. (ConstraintsB b, AllB c b) => b f -> b (Dict c `Product` f) -- | Deprecated: Class was renamed to ProductBC type ProofB b = ProductBC b -- | Deprecated: Renamed to bdicts bproof :: forall b c. (ProductBC b, AllB c b) => b (Dict c) -- | We get a container of a's for any Barbie-type when we make it -- wear a (Const a) . The Container wrapper gives -- us the expected instances for a container type. module Data.Barbie.Container -- | Wrapper for container-Barbies. newtype Container b a Container :: b (Const a) -> Container b a [getContainer] :: Container b a -> b (Const a) instance GHC.Generics.Generic (Data.Barbie.Container.Container b a) instance GHC.Classes.Eq (b (Data.Functor.Const.Const a)) => GHC.Classes.Eq (Data.Barbie.Container.Container b a) instance GHC.Classes.Ord (b (Data.Functor.Const.Const a)) => GHC.Classes.Ord (Data.Barbie.Container.Container b a) instance GHC.Read.Read (b (Data.Functor.Const.Const a)) => GHC.Read.Read (Data.Barbie.Container.Container b a) instance GHC.Show.Show (b (Data.Functor.Const.Const a)) => GHC.Show.Show (Data.Barbie.Container.Container b a) instance Data.Barbie.Internal.Functor.FunctorB b => GHC.Base.Functor (Data.Barbie.Container.Container b) instance Data.Barbie.Internal.Traversable.TraversableB b => Data.Foldable.Foldable (Data.Barbie.Container.Container b) instance Data.Barbie.Internal.Traversable.TraversableB b => Data.Traversable.Traversable (Data.Barbie.Container.Container b) instance Data.Barbie.Internal.Product.ProductB b => GHC.Base.Applicative (Data.Barbie.Container.Container b)