h*_w]9      !"#$%&'()*+,-./0123456780.5 Safe-Inferred/01=]G9flay7INTERNAL. DO NOT EXPORT. Used as a placeholder of kind forall k. k -> :.;flay7INTERNAL. DO NOT EXPORT. Used as a placeholder of kind forall k. k -> :.flayLike , but s is expected to be a <, and the type-constructor f expected to wrap all of the field targets we want to constraint with c should be given explicitly.This = ensures that c is satsfieds by all of the > types appearing in s that are wrapped by f.flay This is like , but it targets only field types that are wrapped by some type-constructor f.That is, for all a in s f such that f a is an immediate children of s f, then c a must be satisfied.8 can be used to remove boilerplate from contexts, since c will need to be mentioned just once, rather than once per type of field. This is particularly useful in the case of datatypes as Foo" below, intended to be used with : data Foo f = Foo (f ?) (f @) +If, for example, you intend to implement a  c (Foo f) (Foo g) f g instance, then constraints c ? and c @. will propagate. However, instead of writing (c ?, c @), you can write  c Foo and achieve the same, which will reduce boilerplate significantly in cases where the number of types contained in f is larger. That is:  forall (c :: : -> =).  c Foo == (c ?, c @)  Notice that  only works with types of kind (k -> :) -> : such as Foo=. That is, types that are parametrized by a type constructor.flayLike , but s is expected to be a <.This = ensures that c is satsfieds by all of the > types appearing in s-, which is expected to be one of the various A representation types.flay5Ensure that all of the immeditate children fields of s satisfy c..For example, in a datatype like the following: data Bar = Bar ? @ The  constraint behaves like this:  c Bar == (c ?, c @) 8 can be used to remove boilerplate from contexts, since c will need to be mentioned just once, rather than once per type of field. This is particularly useful in the case of datatypes as Foo" below, intended to be used with : data Foo f = Foo (f ?) (f @) #The problem with types shaped like Foo8 is that deriving some useful instances for them, like B5, involves a lot of boilerplate. For one, the usual  deriving (B)6 statement doesn't work, and you need to rely on the StandaloneDeriving GHC extension. But even that's not enough, since you need to ensure that B9 constrains the individual field types as well. That is: deriving instance (B (f ?), B (f @)) => B (Foo f) This works, but hopefully you can see how this can become very verbose when you have more than a two or three datatypes in your fields. Instead, provided we derive A for Foo , we can use & to remove that boilerplate. That is: data Foo f = Foo (f ?) (f @) deriving (A) deriving instance  B (Foo f) => B (Foo f) flay Ensure that x, satisfies all of the constraints listed in cs.flay Convenient =$ for satisfying the requirements of  and .flayWrapper allowing a A non  type to become .$Most datatypes that can have useful 9 instances are often parametrized by a type constructor  f :: k -> :8, and have all or some of their fields wrapped in said f , like so: data Foo f = Foo (f ?) (f @) However, that kind of representation is not that common, and it can sometimes be unconfortable to use, particularly if f ~ Identity due to the necessary wrapping and unwrapping of values. In Haskell, it's more common to use a representation like the following for records (or sums): data Bar = Bar ? @ deriving (A) The problem with that representation, however, is that it prevents us to operate on the individual fields as enabled by .' is a wrapper that converts types like Bar into types like Foo. In our concrete case,  Bar f is isomorphic to Foo f. But more importantly,  Bar f automatically gets a + instance of its own, allowing you to use  to operate on  Bar f as you would operate on Foo f.To construct a  you use , and to remove the  wrapper you use +, which satisfy the following identity law:  C .  D == D  relies on Haskell's As, which is why we derived A for our Bar above. If Bar didn't have a A- instance, then you wouldn't be able to use  and would be better served by a manually written functions converting Bar to Foo and back.Keep in mind that  s f will only add f/ wrappers to the immediate children fields of s (which could itself be a sum type or a product type), but it won't recurse into the fields and add f wrappers to them.0Very contrived and verbose example using all of ,  and : =-- | Replaces all of the fields of the given Bar with values E from -- , if possible. qux :: Bar -> F (G H Bar ) qux bar0 = do let pbar0 ::  Bar Identity pbar0 =  Identity bar0 let h ::  (E a) -> Identity a -> F (I a) h  (Identity _) = J  K pbar1 ::  Bar I <-  h pbar0 -- We convert the Is to G. just for demonstration purposes. -- Using  C= would have been enough to make this function -- return a I Bar. let ebar1 :: G H Bar ebar1 =  (L (M "Bad") N) pbar1 pure ebar1 %Or, written in a less verbose manner: qux :: Bar -> F (G H Bar ) qux bar = J ( (L (M "Bad") N)) ( @E (( (Identity _) -> J  K) ( Identity bar)  We can use qux in GHCi as follows: > qux (Bar 0 False)  not a number  not a bool  Left "Bad" > qux (Bar 0 False) 1 True Right (Bar 1 True) flay Witness that a% is a terminal object. That is, that a, can always be constructed out of thin air. flay Convenient =$ for satisfying the requirements of . flay=# trivially satisfied by every type.This can be used as the c parameter to  or  in case you are not interested in observing the values inside f.OflayLike Flayable c (r F) (r G) F G", but with a superfluous trailing x to match the kind expected by P.Qflay This inner Q4 class prevents the skolem from leaking to the user.flay is $ specialized for the common case of s ~ r f and t ~ r g. The rationale for introducing this seemingly redundant constraint is that  is less verbose than .In other words, if we had QuantifiedConstraints, then  would be something like:  c r == forall (f :: k -> : ) (g :: k -> : ).  c (r f) (r g) f g flayDefault  implementation for s and t.When defining  instances, you should leave c, f, and g< fully polymomrphic, as these are the most useful types of  Flayabless.If s and t are instances of A, then , can be used as default implementation for 8. For example, provided the following datatype and its A instance: data Foo f = Foo (f ?) (f @) deriving (A) Then the following 2 instance would get a default implementation for :  instance (c ?, c @) =>  c (Foo f) (Foo g) f g &But actually, this library exports an  OVERLAPPABLE& instance that covers datatypes like Foo above. That is, datatypes parametrized by some type constructor where that type constructor wraps each of the immediate children fields. So ,most times you don't even need to write the  instance yourself. That is, a  c (r f) (r g) f g for r4 types parametrized by a type-constructor, such as Foo , having A instances.)In cases where you do need to define the = instance yourself, you'll notice that constraints applying c> to every immediate child field type will bubble up, such as (c ?, c @)0 in the example above. This module exports the  constraint that can be used to reduce that boilerplate for datatypes that implement A4, tackling all of the fields at once. That is, the  instance for Foo* above could have been written like this:  instance  c Foo =>  c (Foo f) (Foo g) f g  Notice that  can be defined in terms of  as well.flay c s t f g allows converting s to t by replacing ocurrences of f with g' by applicatively applying a function !(forall a. c a => f a -> m (g a)) to targeted occurences of f a inside s.A & must obey the following identity law: forall (fl ::  c s t f g). fl (R D) == D When defining  values, you should leave c, f, and g; fully polymorphic, as these are the most useful types of s.We use  (c a) -> instead of c a => because the latter is often not enough to satisfy the type checker. With this approach, one must explicitly pattern match on the  (c a)# constructor in order to bring the c a0 instance to scope. Also, it's necessary that c$ is explicitly given a type at the Flay's call site, as otherwise the type checker won't be able to infer c on its own.5to flay: tr. v., to strip off the skin or surface of. Mnemonic for  c s t f g%: Much like lenses have type indexes s t a b where s is the input state, t is the output state, and a and b are the input and output values respectively, in , s and t< represent the input and output states like in lenses, and f and g represent the wrappers4 over the input and output values respectively. The c comes at the very beginning because it is the type you are expected to apply with TypeApplications if necessary.Example 1: Removing uncertainty(Consider the following types and values: 8-- | Foo is a higher-kinded type parametrized over some f :: : -> :. data Foo f = Foo (f ?) (f @) deriving instance (B (f ?), B (f @)) => B (Foo f)   flayFoo :: (S m, c ?, c @) => 7 c (Foo f) (Foo g) f g flayFoo h (Foo a b) = Foo <$> h  a <*> h  b   foo1 :: Foo I foo1 = Foo (T 1) U   foo2 :: Foo I foo2 = Foo (T 2) (T V) It is possible to remove the  uncertainty of the fields in Foo perhaps being empty (U) by converting Foo I to Foo Identity3. However, we can't just write a function of type Foo I -> Foo Identity= because we have the possiblity of some of the fields being U , like in foo1). Instead, we are looking for a function Foo I -> I (Foo Identity) which will result on T' only as long as all of the fields in Foo is T , like in foo2. This is exactly what S enables us to do: fooMaybeToIdentity :: Foo I -> I (Foo Identity)) fooMaybeToIdentity (Foo a b) = Foo <$> J D a <*> J D b Example using this in GHCi: > fooMaybeToIdentity foo1 U  > fooMaybeToIdentity foo2 T (Foo (Identity 2) (Identity V)) 4In fact, notice that we are not really working with T, U, nor Identity* directly, so we might as well just leave I and Identity1 polymorphic. All we need is that they both are Ss:  fooMToG :: (S m, S6 g) => Foo m -> m (Foo g) fooMToG (Foo a b) = Foo <$> J D a <*> J D b fooMToG behaves the same as fooMaybeToIdentity2, but more importantly, it is much more flexible: > fooMToG foo2 :: I (Foo []) T (Foo [2] [V])  > fooMToG foo2 :: I (Foo (G H)) T (Foo (N 2) (N V)) , among other things, is intended to generalize this pattern, so that whatever choice of Foo, I or Identity you make, you can use S" this way. The easiest way to use  is through , which is sufficient unless we need to enforce some constraint in the target elements wrapped in m+ inside foo (we don't need this now). With , we could have defined fooMToG this way:  fooMToG :: (S m, S$ g) => Foo m -> m (Foo g) fooMToG =  flayFoo (J D) =Some important things to notice here are that we are reusing flayFoo's knowledge of Foo'*s structure, and that the construction of g using D applies to any value wrapped in m (? and @* in our case). Compare this last fact to W, where the types of the targets must be the same, and known beforehand.Also, notice that we inlined flayFoo for convenience in this example, but we could as well have taken it as an argument, illustrating even more how 7 decouples the shape and targets from their processing:  flayMToG :: (S m, S g) =>   % m s t m g -> s -> m s flayMToG fl =  fl (J D) This is the esscence of 7: We can work operating on the contents of a datatype s targeted by a given  without knowing anything about s, nor about the  forall x. f x targets of the :. And we do this using an principled approach relying on S and X. We can use a  to repurpose a datatype while maintaining its "shape". For example, given Foo: Foo Identity( represents the presence of two values ? and Y, Foo I& represents their potential absence, Foo []+ represents the potential for zero or more ?s and Ys, Foo (Z x). represent the presence of two values of type x, and Foo F represents two F, actions necessary to obtain values of type ? and Y . We can use flayFoo to convert between these representations. In all these cases, the shape of Foo is preserved, meaning we can continue to pattern match or project on it. Notice that even though in this example the f argument to Foo happens to always be a X , this is not necessary at all.Example 2: Standalone mIn the previous example, flayFoo took the type Flay   (Foo m) (Foo g) m g when it was used in flayMToG . That is, m and f were unified by our use of J. However, keeping these different opens interesting possibilities. For example, let's try and convert a Foo I to a Foo (G H), prompting the user for the M side of that G0 whenever the original target value is missing.  prompt :: F H prompt = do [$ "Missing value! Error message? " K  fooMaybeToEitherIO :: Foo I -> F (Foo (G H)) fooMaybeToEitherIO =  flayFoo $ \case U -> J M prompt T x -> D (N x) Using this in GHCi: 8> fooMaybeToEitherIO foo1 Missing value! Error message?  Nooooo!!!!! Foo (N 1) (M "Nooooo!!!!!")  > fooMaybeToEitherIO foo2 Foo (N 2) (N V) Example 3: ContextsExtending the previous example we "replaced" the missing values with a H, but wouldn't it be nice if we could somehow prompt a replacement value of the original type instead? That's what the c argument to  is for. Let's replace prompt- so that it can construct a type other than H:  prompt :: E x => F x prompt = do [" "Missing value! Replacement? " \  Notice how prompt now has a E x7 constraint. In order to be able to use the result of prompt, as a replacement for our missing values in Foo I, we will have to mention E as the c argument to , which implies that E will have to be a constraint satisfied by all of the targets of our  (as seen in the constraints in flayFoo). We can't use  anymore, we need to use flayFoo directly: fooMaybeToIdentityIO :: Foo I -> F (Foo Identity0) fooMaybeToIdentityIO = flayFoo h where h ::  (E a) -> I a -> F (Identity a) h  = \case U -> J D prompt T a -> D (D a) ;Notice how we had to give an explicit type to our function h#: This is because can't infer our E a constraint. You will always need to explicitly type the received  unless the c argument to  has been explicitly by other means (like in the definition of *, where we don't have to explicitly type  because c ~  * according to the top level signature of  ). Using the TypeApplications) GHC extension might make things easier: fooMaybeToIdentityIO :: Foo I -> F (Foo Identity)) fooMaybeToIdentityIO = flayFoo @Read (\ -> \case U -> J D prompt T a -> D (D a)) Example using this in GHCi: 8> fooMaybeToIdentityIO foo1 Missing value! Replacement? V Foo (Identity 1) (Identity V)  !> fooMaybeToIdentityIO foo2 Foo (Identity 2) (Identity V) (Of course, as in our previous examples, Identity% here could have generalized to any S. We just fixed it to Identity as an example.3You can mention as many constraints as you need in c as long as c has kind k -> = (where k is the kind of f's argument). You can always group together many constraints as a single new one in order to achieve this. For example, if you want to require both B and E= on your target types, then you can introduce the following  ShowAndRead class, and use that as your c. class (B a, E a) => ShowAndRead a instance (B a, E a) => ShowAndRead a (This is such a common scenario that the Flay module exports , a = you can use to apply many =0s at once. For example, instead of introducing  ShowAndRead, we could use  '[B, E] as our c argument to ', and the net result would be the same. Example 4: See the documentation for . To sum up: for any given , we can collect all of the Flay's targets into a ], without knowing anything about the targets themselves beyond the fact that they satisfy a particular constraint.flayLike , but specialized to work on .flayGiven a  for any constraint c obtain a  for a   constraint.flay You can use  if you don't care about the c argument to 6. This implies that you won't be able to observe the a in  forall a. f a, all you can do with such a is pass it around. forall (fl ::    s t f g) (h :: S m =>    -> f a -> m (g a)).  fl h == fl (R h) flayLike , but works on a  instead of taking an explicit .  =   flayLike , but works on a  instead of taking an explicit .  =   flayCollect all of the f a of the given  into a ] b.Example usage, given Foo and flayFoo* examples given in the documentation for : >  flayFoo (\( ::  (B a)) (Identity (a :: a)) -> [^ a]) (Foo (D 4) (D V)) ["4","True"] flayLike , but works on a  instead of an explicit .flayLike , but works on a  instead of an explicit .flayZip two  s together.Example pairing two of the Foo$ values seen elsewhere in this file.  > let foo1 = Foo (  0) (  _ ) > :: Foo   > let foo2 = Foo (T 1) U > :: Foo I >  (( ::  (  x)) a b -> D (` a b)) foo1 foo2 > :: S m => m (I (Foo (a   I))) T (Foo (` (  0) (T 1)) (` (  _) U)) >  (( ::  (B x)) ( ! a) yb -> case yb of > U -> D (Z (^ a)) > T b -> D (Z (^$ (a, b))) ) > foo1 foo2 > :: S m => m (I (Foo (Z H))) T (Foo (Z "(0,1)") (Z "False")) Returns U0 in case the indivual target types do not match.Note:  is safer but less general than .flayZip two  s together. is like  , but for s.Returns U0 in case the indivual target types do not match.Note:  is safer but less general than .flayUnsafe version of ' that doesn't guarantee that the given s target the same values.  and * make this function safe by simply using  or  three times.Returns U0 in case the indivual target types do not match.flayWrap s in  so that it can be ed.See the documentation for  for more details.flay Remove the  wraper around s.See the documentation for  for more details.'flay6All datatypes parametrized over some type constructor  f :: k -> : that have a A instance get a  instance for free. For example: data Foo f = Foo (f ?) (f @) deriving (A)  This is an  OVERLAPPABLE instance, meaning that you can provide a different instance for your A datatype, if necessary.flayHow to wrap in f each individual child field of s.flayHow to remove the f# wrapper from every child field of  s f.             !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHICDJGHKCDLCDMGHNGOPGQRGQSGTUCDVGWXGQYGZ[GQ\G]G^_GW`GWabcdGQeGQfGZgGZhCDiGjkGQlCDmGnoGpGqGQrGOsCDtGuvGuwflay-0.5-EdZIFJ96b5gLL92UAbrjTKFlayflay System.IOstdin Text.Read readMaybeTextData.Functor.IdentityIdentity)constraints-0.14.2-G9UcjEhPYHSDB7oJUfrOiKData.ConstraintDictGFieldsFFieldsFGFieldsFieldsAllGPumpPump GTerminalTerminalterminalGFlayTrivial Flayable1Flayableflay1 trivializetrivial'trivialtrivial1gflaycollect'collectcollect1zip1zip unsafeZippumpdump $fTrivialka$fGFlay'kkc:+::+:fg$fGFlay'kkc:*::*:fg$fGFlay'kkcM1M1fg$fGFlay'kkcK1K1fg$fGFlay'kkcU1U1fg$fGFlay'kkcV1V1fg$fFlayablekcrrfg$fTerminalConst $fTerminal()$fGTerminal:*: $fGTerminalM1 $fGTerminalK1 $fGTerminalU1 $fTerminala $fGPump'k:+:f $fGPump'k:*:f $fGPump'kM1f $fGPump'kK1f $fGPump'kU1f $fGPump'kV1f$fFlayableTYPEcPumpPumpfg$fFieldsF_kkcr$fFlayable1Kkcrx$fFlayable1_kcrGghc-prim GHC.TypesTypeFbase GHC.GenericsRep ConstraintK1IntBoolGenericGHC.ShowShowGHC.BaseidpureGHC.ReadReadIO Data.EitherEitherString GHC.MaybeMaybefmapgetLine Data.MaybemaybeLeftRight Flayable1KSkolem Flayable1_const ApplicativeJustNothingTrueData.TraversabletraverseFunctorCharData.Functor.ConstConstputStrreadLnMonoidshowFalseData.Functor.ProductPairProduct