úξ9º*      !"#$%&'()Safe+,-7;<=>?AFQSTV¸ø Ensure that x, satisfies all of the constraints listed in cs. Witness that a% is a terminal object. That is, that a, can always be constructed out of thin air.  Convenience * for satisfying basic  needs for s and t. *# 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.   is  $ specialized for the common case of s ~ r f and t ~ r gL. The rationale for introducing this seemingly redundant class is that the  ! constraint is less verbose than  .@Unfortunately, we can't readily existentialize the arguments to  ,, which is why you'll need to specify both   and  # instances. Notice, however, that   can be defined in terms of 3 and vice-versa, so this should be very mechanical. If r f and r g are instances of +, then  ; gets a default implementation. For example, provided the Foo* datatype shown in the documentation for  had a + instance, then the following  1 instance would get a default implementation for  :  instance (c ,, c -) =>   c Foo  Notice that   can be defined in terms of  as well. Default  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 +, then , can be used as default implementation for . For example, provided the Foo* datatype shown in the documentation for  had a + instance, then the following  2 instance would get a default implementation for :  instance (c ,, c -) =>   c (Foo f) (Foo g) f g where  =   Notice that  can be defined in terms of   as well.Implementors note:> Unfortunately, due to some strange bug in GHC, we can't use DefaultSignatures to say  = ', because when doing that the kind of c infers incorrectly. 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  identity law.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'Cs 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: Common STandard FoG.Example 1: Removing uncertainty(Consider the following types and values: data Foo f = Foo (f ,) (f -) deriving instance (. (f ,), . (f -)) => . (Foo f)   flayFoo :: (/ m, c ,, c -) => 7 c (Foo f) (Foo g) f g flayFoo h (Foo a b) = Foo <$> h  a <*> h  b   foo1 :: Foo 0 foo1 = Foo (1 1) 2   foo2 :: Foo 0 foo2 = Foo (1 2) (1 3) It is possible to remove the  uncertainty of the fields in Foo perhaps being empty (2) by converting Foo 0 to Foo 43. However, we can't just write a function of type Foo 0 -> Foo 4= because we have the possiblity of some of the fields being 2 , like in foo1). Instead, we are looking for a function Foo 0 -> 0 (Foo 4) which will result on 1' only as long as all of the fields in Foo is 1 , like in foo2. This is exactly what / enables us to do: fooMaybeToIdentity :: Foo 0 -> 0 (Foo 4)) fooMaybeToIdentity (Foo a b) = Foo <$> 5 6 a <*> 5 6 b Example using this in GHCi: > fooMaybeToIdentity foo1 2  > fooMaybeToIdentity foo2 1 (Foo (4 2) (4 3)) 4In fact, notice that we are not really working with 1, 2, nor 4* directly, so we might as well just leave 0 and 41 polymorphic. All we need is that they both are /s:  fooMToG :: (/ m, /6 g) => Foo m -> m (Foo g) fooMToG (Foo a b) = Foo <$> 5 6 a <*> 5 6 b fooMToG behaves the same as fooMaybeToIdentity2, but more importantly, it is much more flexible: > fooMToG foo2 :: 0 (Foo []) 1 (Foo [2] [3])  > fooMToG foo2 :: 0 (Foo (7 8)) 1 (Foo (9 2) (9 3)) Z, among other things, is intended to generalize this pattern, so that whatever choice of Foo, 0 or 4 you make, you can use /" this way. The easiest way to use  is through d, 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 :: (/ m, /$ g) => Foo m -> m (Foo g) fooMToG =  flayFoo (5 6) =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 6 applies to any value wrapped in m (, and -* in our case). Compare this last fact to :I, where the types of the targets must be the same, and known beforehand.Also, notice that we inlined flayFoor 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 :: (/ m, / g) =>   % m s t m g -> s -> m s flayMToG fl =  fl (5 6) 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 / and ;. We can use a L to repurpose a datatype while maintaining its "shape". For example, given Foo: Foo 4( represents the presence of two values , and <, Foo 0& represents their potential absence, Foo []+ represents the potential for zero or more ,s and <s, Foo (= x). represent the presence of two values of type x, and Foo > represents two >, actions necessary to obtain values of type , and < . We can use flayFooM to convert between these representations. In all these cases, the shape of Foox 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 ; , 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 5j. However, keeping these different opens interesting possibilities. For example, let's try and convert a Foo 0 to a Foo (7 8), prompting the user for the ? side of that 70 whenever the original target value is missing.  prompt :: > 8 prompt = do @$ "Missing value! Error message? " A  fooMaybeToEitherIO :: Foo 0 -> > (Foo (7 8)) fooMaybeToEitherIO =  flayFoo $ \case 2 -> 5 ? prompt 1 x -> 6 (9 x) Using this in GHCi: 8> fooMaybeToEitherIO foo1 Missing value! Error message?  Nooooo!!!!! Foo (9 1) (? "Nooooo!!!!!")  > fooMaybeToEitherIO foo2 Foo (9 2) (9 3) Example 3: ContextsHExtending the previous example we "replaced" the missing values with a 8x, 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 8:  prompt :: B x => > x prompt = do @" "Missing value! Replacement? " C  Notice how prompt now has a B x7 constraint. In order to be able to use the result of prompt, as a replacement for our missing values in Foo 0, we will have to mention B as the c argument to , which implies that BF 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 0 -> > (Foo 40) fooMaybeToIdentityIO = flayFoo h where h ::  (B a) -> 0 a -> > (4 a) h  = \case 2 -> 5 6 prompt 1 a -> 6 (6 a) ;Notice how we had to give an explicit type to our function h#: This is because can't infer our B aC 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 ).Example using this in GHCi: 8> fooMaybeToIdentityIO foo1 Missing value! Replacement? 3 Foo (4 1) (4 3)  !> fooMaybeToIdentityIO foo2 Foo (4 2) (4 3) (Of course, as in our previous examples, 4% here could have generalized to any /. We just fixed it to 4 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 . and B= on your target types, then you can introduce the following  ShowAndRead class, and use that as your c. class (. a, B a) => ShowAndRead a instance (. a, B 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] 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 Dt, without knowing anything about the targets themselves beyond the fact that they satisfy a particular constraint.Inner identity law: (\fl -> E .  fl 6) = F Given a  for any constraint c obtain a  for a   constraint. 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.  fl h = fl (\( ::  (  a)) (fa :: f a) -> h fa) Like , but works on a   instead of taking an explicit .  =   Like , but works on a   instead of taking an explicit .  =    Collect all of the f a of the given  into a D b.Example usage, given Foo and flayFoo* examples given in the documentation for : >  flayFoo (\( ::  (. a)) (4 (a :: a)) -> [G a]) (Foo (6 4) (6 3)) ["4","True"] Like , but works on a   instead of an explicit .Like , but works on a   instead of an explicit .Zip two   s together.Example pairing two of the Foo$ values seen elsewhere in this file.  > let foo1 = Foo (4 0) (4 H ) > :: Foo 4 > let foo2 = Foo (1 1) 2 > :: Foo 0 >  (( ::  (  x)) a b -> I a b) foo1 foo2 > :: Foo (J 4 0) Foo (I (4 0) (1 1)) (I (4 H) 2) >  (( ::  (. x)) (4! a) yb -> case yb of > 2 -> = (G a) > 1 b -> = (G( (a, b)) ) > foo1 foo2 > :: Foo (= 8) Foo (= "(0,1)") (= "False") Returns 20 in case the indivual target types do not match.Note:  is safer but less general than .Zip two   s together. is like  , but for  s.Returns 20 in case the indivual target types do not match.Note:  is safer but less general than .Unsafe 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 20 in case the indivual target types do not match.        K      !"#$%&'()*+,-./01,-2,-3/45/67/68/69/6:,-;/<=/6>/6?/@A/6B/@C/DE/6F,-G/HI,-J/@K/LM/LN/OP/LQ/6R/<S/6T/4U,-V/WX/WYZflay-0.3-8J8uniXdecH2iUIk77F1sgFlay'constraints-0.10-ESmMQffnwN84zRaznSOsyKData.ConstraintDictAll GTerminal gterminalTerminalterminalGFlay'gflay'GFlayTrivial Flayable1flay1Flayableflayinner trivializetrivial'trivialtrivial1gflaycollect'collectcollect1zip1zip unsafeZip $fTrivialka$fGFlay'kkc:+::+:fg$fGFlay'kkc:*::*:fg$fGFlay'kkcM1M1fg$fGFlay'kkcK1K1fg$fGFlay'kkcV1V1fg $fGFlaykcstfg$fTerminalConst $fTerminal()$fGTerminal:*: $fGTerminalM1 $fGTerminalK1 $fTerminala $fAllkcsxghc-prim GHC.Types Constraintbase GHC.GenericsGenericIntBoolGHC.ShowShowGHC.Base ApplicativeMaybeJustNothingTrueData.Functor.IdentityIdentityfmappure Data.EitherEitherStringRightData.TraversabletraverseFunctorCharData.Functor.ConstConstIOLeft System.IOputStrgetLineGHC.ReadReadreadLnMonoid runIdentityidshowFalseData.Functor.ProductPairProduct