X\      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[(C) 2012-2013 Edward Kmett BSD-style (see the file LICENSE)Edward Kmett <ekmett@gmail.com> experimental non-portableNone!"3457;>IKLNBThe  forms the bulk of a .A * is a recorded path through the (indexed) \ chain of a .This enables us to pull the  back up to the .A H is a linked list of the levels above the current one. The length of a  is known at compile time.,This is part of the internal structure of a 1. You shouldn't need to manipulate this directly. This represents the type a  will have when it is fully   back up. Many zippers are indexed by Int keys. This type alias is convenient for reducing syntactic noise for talking about these boring indices. This type family represents a  with the pD variable abstracting over the position and the index, in terms of  1. You can visually see it in type signatures as: h   (a   i) =  h i a FAn empty data type, used to represent the pairing of a position in a  with an index. See  .This is the type of a . It visually resembles a "breadcrumb trail" as used in website navigation. Each breadcrumb in the trail represents a level you can move up to.EThis type operator associates to the left, so you can use a type like    (],^)   ]   _to represent a  from (],^) down to _) that has an intermediate crumb for the ] containing the _.You can construct a  into *any* data structure with +.'You can repackage up the contents of a  with E.rezip $ zipper 4242HThe combinators in this module provide lot of things you can do to the  while you have it open.Note that a value of type h   s   a+ doesn't actually contain a value of type h   sN -- as we descend into a level, the previous level is unpacked and stored in  form. Only one value of type _   _3 exists at any particular time for any particular .This is used to represent the  of the .Every  starts with .e.g.    a is the type of the trivial .A  into a  that ends at a .Once we've updated a : we need to put the values back into the original shape.  is an illegal `% that is used to put the values back.A $ is used to store the contents of a \ in a way that we do not have to re-asocciate the elements. This enables us to more gracefully deal with infinite traversals.)Return the number of children in a jacketCThis is an internal function used to check from left-to-right if a  has any  nots or not.CThis is an internal function used to check from right-to-left if a  has any  nots or not./This is used to extract the maximal key from a . This is used by ; and :d to seek specific keys, borrowing the asympotic guarantees of the original structure in many cases!  Construct a  from a a!Given a a and a  build from that a with  , refill the a with its new contents."This is only a valid b& if you don't change the shape of the !#'Calculate the absolute position of the  targeted by a .YThis can be quite expensive for right-biased traversals such as you receive from a list.$+Return the total number of children in the  by walking the  to the root.%Reconstruct a  from a .&)Walk down the tree to the leftmost child.'*Walk down the tree to the rightmost child.(Move left one .)Move right one .*This b! views the current target of the .+ Construct a 0 that can explore anything, and start it at the .,Return the index of the focus.-"Return the index into the current \! within the current level of the . 8 (- l) l = c'Mnemonically, zippers have a number of 7" within each level. This is which - you are currently at.vThis is based on ordinal position regardless of the underlying index type. It may be excessively expensive for a list.,# may be much cheaper if you have a \ indexed by ordinal position!. Move the  .?, closing the current level and focusing on the parent element.%NB: Attempts to move upward from the  of the  will fail to typecheck./ Jerk the  one - to the / within the current b or \./Attempts to move past the start of the current \ (or trivially, the current b) will return d.&isNothing $ zipper "hello" & rightwardTrue?zipper "hello" & fromWithin traverse & rightward <&> view focus'e'Kzipper "hello" & fromWithin traverse & rightward <&> focus .~ 'u' <&> rezip"hullo"Crezip $ zipper (1,2) & fromWithin both & tug rightward & focus .~ 3(1,3)0 Jerk the  0 one - within the current b or \.-Attempts to move past the end of the current \ (or trivially, the current b) will return d.%isNothing $ zipper "hello" & leftwardTrue1-Move to the leftmost position of the current \.$This is just a convenient alias for 5 0.Fzipper "hello" & fromWithin traverse & leftmost & focus .~ 'a' & rezip"aello"2.Move to the rightmost position of the current \.$This is just a convenient alias for 5 /.azipper "hello" & fromWithin traverse & rightmost & focus .~ 'y' & leftmost & focus .~ 'j' & rezip"jelly"3This allows you to safely 3 0 or 3 / on a @. This will attempt the move, and stay where it was if it fails.JThe more general signature allows its use in other circumstances, however. 3 f x "a e a (f a)Ofmap rezip $ zipper "hello" & within traverse <&> tug leftward <&> focus .~ 'j'"jello"Pfmap rezip $ zipper "hello" & within traverse <&> tug rightward <&> focus .~ 'u'"hullo"4This allows you to safely 3 0 or 3 / multiple times on a , moving multiple steps in a given direction and stopping at the last place you couldn't move from. This lets you safely move a %, because it will stop at either end.Sfmap rezip $ zipper "stale" & within traverse <&> tugs rightward 2 <&> focus .~ 'y'"style"prezip $ zipper "want" & fromWithin traverse & tugs rightward 2 & focus .~ 'r' & tugs leftward 100 & focus .~ 'c'"cart"5:Move in a direction as far as you can go, then stop there.4This repeatedly applies a function until it returns f#, and then returns the last answer.dfmap rezip $ zipper ("hello","world") & downward _1 & within traverse <&> rightmost <&> focus .~ 'a'("hella","world")Xrezip $ zipper ("hello","there") & fromWithin (both.traverse) & rightmost & focus .~ 'm'("hello","therm")6)This allows for you to repeatedly pull a 7 in a given direction, failing if it falls off the end.CisNothing $ zipper "hello" & within traverse >>= jerks rightward 10TrueTfmap rezip $ zipper "silly" & within traverse >>= jerks rightward 3 <&> focus .~ 'k'"silky"7;Returns the number of siblings at the current level in the . 7 z g 1NB: If the current \D targets an infinite number of elements then this may not terminate.QThis is also a particularly expensive operation to perform on an unbalanced tree. zipper ("hello","world") & teeth12zipper ("hello","world") & fromWithin both & teeth2.zipper ("hello","world") & downward _1 & teeth1Dzipper ("hello","world") & downward _1 & fromWithin traverse & teeth5;zipper ("hello","world") & fromWithin (_1.traverse) & teeth5=zipper ("hello","world") & fromWithin (both.traverse) & teeth108 Move the $ horizontally to the element in the nIth position in the current level, absolutely indexed, starting with the 5 0 as 0. This returns d% if the target element doesn't exist. 8 n "a 6 / n h 5 0-isNothing $ zipper "not working." & jerkTo 20True9 Move the $ horizontally to the element in the nIth position of the current level, absolutely indexed, starting with the 5 0 as 0.QIf the element at that position doesn't exist, then this will clamp to the range 0 i n j 7. 9 n "a 4 / n h 5 0grezip $ zipper "not working." & fromWithin traverse & tugTo 100 & focus .~ '!' & tugTo 1 & focus .~ 'u'"nut working!":/Move towards a particular index in the current \.;(Move horizontally to a particular index i in the current \.. In the case of simple zippers, the index is k3 and we can move between traversals fairly easily:;zipper (42, 32) & fromWithin both & moveTo 0 <&> view focus42;zipper (42, 32) & fromWithin both & moveTo 1 <&> view focus32< Construct an l from m where the index is fixed to 0.=Step down into a b . This is a constrained form of CF for when you know there is precisely one target that can never fail. = :: n s a -> (h   s) -> h   s   a = :: o s a -> (h   s) -> h   s   a >Step down into a l . This is a constrained form of DF for when you know there is precisely one target that can never fail. > :: p i s a -> (h   s:@j) -> h   s:@j   a:@i ?Step down into the 1 entry of a \. ? :: q s a -> (h   s:@j) -> r (h   s:@j   a) ? :: s s a -> (h   s:@j) -> r (h   s:@j   a) ? :: n s a -> (h   s:@j) -> r (h   s:@j   a) ? :: o s a -> (h   s:@j) -> r (h   s:@j   a) ? :: t m => u s a -> (h   s:@j) -> m (h   s:@j   a) @Step down into the 1 entry of an v.Note:` The index is assumed to be ordered and must increase monotonically or else you cannot (safely) ; or : or use tapes. @ :: w i s a -> (h   s:@j) -> r (h   s:@j   a:@i) @ :: p i s a -> (h   s:@j) -> r (h   s:@j   a:@i) @ :: t m => u s a -> (h   s:@j) -> m (h   s:@j   a) A Step down into every entry of a \ simultaneously.zipper ("hello","world") & withins both >>= leftward >>= withins traverse >>= rightward <&> focus %~ toUpper <&> rezip :: [(String,String)]I[("hEllo","world"),("heLlo","world"),("helLo","world"),("hellO","world")] A :: q s a -> (h   s:@j) -> [h   s:@j   a] A :: n s a -> (h   s:@j) -> [h   s:@j   a] A :: o s a -> (h   s:@j) -> [h   s:@j   a] B!Step down into every entry of an v simultaneously.Note:` The index is assumed to be ordered and must increase monotonically or else you cannot (safely) ; or : or use tapes. B :: w i s a -> (h   s:@j) -> [h   s:@j   a:@i] B :: p i s a -> (h   s:@j) -> [h   s:@j   a:@i] CUnsafely step down into a \ that is assumed to be non-empty.GIf this invariant is not met then this will usually result in an error! C :: q s a -> (h   s:@j) -> h   s:@j   a C :: n s a -> (h   s:@j) -> h   s:@j   a C :: o s a -> (h   s:@j) -> h   s:@j   a <You can reason about this function as if the definition was: C l "a x h ? l DUnsafey step down into an v that is assumed to be non-emptyGIf this invariant is not met then this will usually result in an error! D :: w i s a -> (h   s:@j) -> h   s:@j   a:@i D :: p i s a -> (h   s:@j) -> h   s:@j   a:@i <You can reason about this function as if the definition was: C l "a x h ? l E-Close something back up that you opened as a .FExtract the current * from a  as a y#, with access to the current index.GSave the current path as as a  we can play back later.H>Restore ourselves to a previously recorded position precisely.*If the position does not exist, then fail.IFRestore ourselves to a location near our previously recorded position.$When moving left to right through a \1, if this will clamp at each level to the range 0 i k j 7c, so the only failures will occur when one of the sequence of downward traversals find no targets.J4Restore ourselves to a previously recorded position.qThis *assumes* that nothing has been done in the meantime to affect the existence of anything on the entire path.Motions 0 or /1 are clamped, but all traversals included on the  are assumed to be non-empty.+Violate these assumptions at your own risk!K5This is used to peel off the path information from a 7 for use when saving the current path for later replay.L>Restore ourselves to a previously recorded position precisely.*If the position does not exist, then fail.MFRestore ourselves to a location near our previously recorded position. When moving 0 to / through a \0, if this will clamp at each level to the range 0 i k j 7c, so the only failures will occur when one of the sequence of downward traversals find no targets.N4Restore ourselves to a previously recorded position.lThis *assumes* that nothing has been done in the meantime to affect the existence of anything on the entire .Motions 0 or /1 are clamped, but all traversals included on the  are assumed to be non-empty.+Violate these assumptions at your own risk!RThis is an illegal `.UThis is an illegal z._  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOP{|}QRSTUVWXYZ[O  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMN\[ZYXWVU TSR!"Q#$%&'()  *+,-./0123456789:;<=>?@ABCDPOEFGHIJKLMNP  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOP{|}QRSTUVWXYZ[   (C) 2012-13 Edward Kmett BSD-style (see the file LICENSE)Edward Kmett <ekmett@gmail.com> experimental non-portableNone' *+-./0123456789:;=>?@ABCDEFGHIJ' +*F.=>?@AB0/123465-789;:E GHICDJ~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`ab`ac]^dZefZ[g]^h]^i]jk]^l`mn]^o`mp`mq`arZ[sZtuZ[vZ[wZ[xZ[y]^zZ[{]^|Z}~Z[Z[]jZ]^zippe_KxOQNNFXQ5yGvO2er2uoXyControl.Zipper.InternalControl.ZipperTrackForkTapeZippingrecoilCoilSnocZipped:>>:>:@ZipperTopPathApLApRStartFlowrunFlowJacketApLeafPuresizenullLeft nullRightmaximal jacketIns jacketOutsjacketoffsetpathsize recompressstartlstartrmovelmoverfocuszipper focalPointtoothupward rightwardleftwardleftmost rightmosttugtugsfarthestjerksteethjerkTotugTo moveTowardmoveTolenseddownward idownwardwithiniwithinwithinsiwithins fromWithin ifromWithinrezipfocusedContextsaveTape restoreTaperestoreNearTapeunsafelyRestoreTapepeel restoreTrackrestoreNearTrackunsafelyRestoreTrack$fZippingZippera $fZippingTopa $fFunctorPath$fApplicativeFlow $fApplyFlow $fFunctorFlow$fMonoidJacket$fTraversableWithIndexiJacket$fFoldableWithIndexiJacket$fFunctorWithIndexiJacket$fTraversableJacket$fFoldableJacket$fFunctorJacketlens_KgvaV1Y0kP54rcZ9J9yx7OControl.Lens.Type TraversalbaseGHC.BaseStringghc-prim GHC.TypesDoubleChar ApplicativeControl.Lens.Internal.BazaarBazaarLensJustmzero Data.Maybe fromMaybeNothing GHC.Classes>=.<=<Int IndexedLensControl.Lens.LensALensLens'Iso' IndexedLens' Traversal'MaybePrism' MonadPlusControl.Lens.Traversal ATraversal'IndexedTraversalIndexedTraversal'fromJustControl.Lens.Internal.ContextPretextMonoidTFCo:R:ZippedZippersTFCo:R:ZippedTopa TFCo:R::>h:@