-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A Pretty Extraordinary Zipper library -- -- PEZ is a generic zipper library. It uses lenses from the -- fclabels package to reference a "location" to move to in the -- zipper. The zipper is restricted to types in the Typeable -- class, allowing the user to "move up" through complex data structures -- such as mutually-recursive types. -- -- Both the Typeable class and fclabels lenses can be derived in GHC, -- making it easy for the programmer to use a zipper with a minimum of -- boilerplate. -- -- Please send any feature requests or bug reports along. -- -- Changes 0.0.4 -> 0.1.0: -- --
--   - use fclabels 1.0
--   - module renamed Data.Label.Zipper
--   - 'ZPath' renamed 'Motion', define new Up type and instance
--   - fclabels lenses now require wrapping with 'to'
--   - 'moveTo' changed to 'move'
--   - savedLens renamed flatten
--   - SavedPath renamed To
--   - removed experimental operators
--   - using failure package for exceptions
--   - etc., etc.
--   
@package pez @version 0.1.0 -- | PEZ is a generic zipper library. It uses lenses from the -- fclabels package to reference a "location" to move to in the -- zipper. The zipper is restricted to types in the Typeable -- class, allowing the user to "move up" through complex data structures -- such as mutually-recursive types, where the compiler could not -- otherwise type-check the program. . Both the Typeable class and -- fclabels lenses can be derived in GHC, making it easy for the -- programmer to use a zipper with a minimum of boilerplate. module Data.Label.Zipper -- | Encapsulates a data type a at a focus b, supporting -- various Motion operations data Zipper a b -- | create a zipper with the focus on the top level. zipper :: a -> Zipper a a -- | re-assembles the data structure from the top level, returning -- Nothing if the structure cannot be re-assembled. -- -- Note: For standard lenses produced with mkLabels this -- will never fail. However setters defined by hand with lens can -- be used to enforce arbitrary constraints on a data structure, e.g. -- that a type Odd Int can only hold an odd integer. This -- function returns Nothing in such cases, which corresponds to -- the LensSetterFailed constructor of UpErrors close :: Zipper a b -> Maybe a -- | Types of the Motion class describe "paths" up or down (so to speak) -- through a datatype. The exceptions thrown by each motion are -- enumerated in the associated type ThrownBy mot. The -- Motion type that will return the focus to the last location -- after doing a 'moveSaving is given by Returning mot. class Exception (ThrownBy mot) => Motion mot where { type family ThrownBy mot :: *; type family Returning mot :: * -> * -> *; { move mot z = moveSaving mot z >>= return . snd } } move :: (Motion mot, Typeable b, Typeable c, Failure (ThrownBy mot) m) => mot b c -> Zipper a b -> m (Zipper a c) moveSaving :: (Motion mot, Typeable b, Typeable c, Failure (ThrownBy mot) m) => mot b c -> Zipper a b -> m ((Returning mot) c b, Zipper a c) -- | a Motion upwards in the data type. e.g. move (Up 2) -- would move up to the grandparent level, as long as the type of the -- focus after moving is b. Inline type signatures are often -- helpful to avoid ambiguity, e.g. (Up 2 :: Up Char (Tree -- Char)) read as "up two levels, from a focus of type Char -- to Tree Char". -- -- This Motion type throws UpErrors newtype Up c b Up :: Int -> Up c b upLevel :: Up c b -> Int -- | indicates a Motion upwards in the zipper until we arrive at a -- type which we can cast to b, otherwise throwing -- UpErrors data UpCasting c b UpCasting :: UpCasting c b -- | A Motion type describing an incremental path "down" through a -- data structure. Use to to move to a location specified by a -- fclabels lens. -- -- Use restore to return to a previously-visited location in a -- zipper, with previous history intact, so: -- --
--   (\(l,ma)-> move l <$> ma) (closeSaving z)  ==  Just z
--   
-- -- Use flatten to turn this into a standard fclabels lens, -- flattening the incremental move steps. -- -- Throws errors of type ToErrors: data To a b -- | use a fclabels label to define a Motion "down" into a data -- type. to :: (Typeable a, Typeable b) => (a :~> b) -> To a b -- | The root of the exception hierarchy for Zipper move operations: data ZipperException data UpErrors CastFailed :: UpErrors LensSetterFailed :: UpErrors MovePastTop :: UpErrors data ToErrors LensGetterFailed :: ToErrors -- | Apply a motion each time the focus matches the predicate, raising an -- error in m otherwise moveWhile :: (Failure (ThrownBy mot) m, Motion mot, Typeable c) => (c -> Bool) -> mot c c -> Zipper a c -> m (Zipper a c) -- | Apply a motion zero or more times until the focus matches the -- predicate -- --
--   moveUntil p = moveWhile (not . p)
--   
moveUntil :: (Failure (ThrownBy mot) m, Motion mot, Typeable c) => (c -> Bool) -> mot c c -> Zipper a c -> m (Zipper a c) -- | Apply the given Motion to a zipper until the Motion fails, returning -- the last location visited. For instance moveFloor (to left) z -- might return the left-most node of a zippered tree z. -- --
--   moveFloor m z = maybe z (moveFloor m) $ move m z
--   
moveFloor :: (Motion m, Typeable a, Typeable b) => m b b -> Zipper a b -> Zipper a b focus :: Arrow ~> => Lens ~> (Zipper a b) b -- | a view function for a Zipper's focus. -- --
--   viewf = get focus
--   
viewf :: Zipper a b -> b -- | set the Zipper's focus. -- --
--   setf = set focus
--   
setf :: b -> Zipper a b -> Zipper a b -- | modify the Zipper's focus. -- --
--   modf = modify focus
--   
modf :: (b -> b) -> Zipper a b -> Zipper a b -- | returns True if Zipper is at the top level of the data -- structure: atTop :: Zipper a b -> Bool -- | Return our zero-indexed depth in the Zipper. if atTop -- zipper then level zipper == 0 level :: Zipper a b -> Int -- | Motion types which alter a Zipper by a knowable integer quantity. -- Concretly, the following should hold: -- --
--   level (move m z) == level z + delta m
--   
-- -- For motions upwards this returns a negative value. class Motion m => LevelDelta m delta :: (LevelDelta m, Typeable a, Typeable b) => m a b -> Int -- | Return a path To the current location in the Zipper. -- This lets you return to a location in your data type with -- restore. -- --
--   save = fst . closeSaving
--   
save :: Zipper a b -> To a b -- | Close the zipper, returning the saved path back down to the zipper's -- focus. See close closeSaving :: Zipper a b -> (To a b, Maybe a) -- | Enter a zipper using the specified Motion. -- -- Saving and restoring lets us for example: find some location within -- our structure using a Zipper, save the location, fmap -- over the entire structure, and then return to where we were safely, -- even if the "shape" of our structure has changed. -- --
--   restore s = move s . zipper
--   
restore :: (Typeable a, Typeable b, Failure ToErrors m) => To a b -> a -> m (Zipper a b) -- | Extract a composed lens that points to the location we saved. This -- lets us modify, set or get a location that we visited with our -- Zipper, after closing the Zipper, using fclabels -- get and set. flatten :: (Typeable a, Typeable b) => To a b -> (a :~> b) -- | a simple type synonym for a Zipper where the type at the focus -- is the same as the type of the outer (unzippered) type. Cleans up type -- signatures for simple recursive types: type Zipper1 a = Zipper a a -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable a typeOf :: Typeable a => a -> TypeRep -- | Derive lenses including type signatures for all the record selectors -- in a datatype. The types will be polymorphic and can be used in an -- arbitrary context. mkLabels :: [Name] -> Q [Dec] -- | Lens type for situations in which the accessor functions can fail. -- This is useful, for example, when accessing fields in datatypes with -- multiple constructors. type :~> f a = MaybeLens f a class Monad f => Failure e f :: (* -> *) failure :: Failure e f => e -> f v -- | Any type that you wish to throw or catch as an exception must be an -- instance of the Exception class. The simplest case is a new -- exception type directly below the root: -- --
--   data MyException = ThisException | ThatException
--       deriving (Show, Typeable)
--   
--   instance Exception MyException
--   
-- -- The default method definitions in the Exception class do what -- we need in this case. You can now throw and catch -- ThisException and ThatException as exceptions: -- --
--   *Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException))
--   Caught ThisException
--   
-- -- In more complicated examples, you may wish to define a whole hierarchy -- of exceptions: -- --
--   ---------------------------------------------------------------------
--   -- Make the root exception type for all the exceptions in a compiler
--   
--   data SomeCompilerException = forall e . Exception e => SomeCompilerException e
--       deriving Typeable
--   
--   instance Show SomeCompilerException where
--       show (SomeCompilerException e) = show e
--   
--   instance Exception SomeCompilerException
--   
--   compilerExceptionToException :: Exception e => e -> SomeException
--   compilerExceptionToException = toException . SomeCompilerException
--   
--   compilerExceptionFromException :: Exception e => SomeException -> Maybe e
--   compilerExceptionFromException x = do
--       SomeCompilerException a <- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make a subhierarchy for exceptions in the frontend of the compiler
--   
--   data SomeFrontendException = forall e . Exception e => SomeFrontendException e
--       deriving Typeable
--   
--   instance Show SomeFrontendException where
--       show (SomeFrontendException e) = show e
--   
--   instance Exception SomeFrontendException where
--       toException = compilerExceptionToException
--       fromException = compilerExceptionFromException
--   
--   frontendExceptionToException :: Exception e => e -> SomeException
--   frontendExceptionToException = toException . SomeFrontendException
--   
--   frontendExceptionFromException :: Exception e => SomeException -> Maybe e
--   frontendExceptionFromException x = do
--       SomeFrontendException a <- fromException x
--       cast a
--   
--   ---------------------------------------------------------------------
--   -- Make an exception type for a particular frontend compiler exception
--   
--   data MismatchedParentheses = MismatchedParentheses
--       deriving (Typeable, Show)
--   
--   instance Exception MismatchedParentheses where
--       toException   = frontendExceptionToException
--       fromException = frontendExceptionFromException
--   
-- -- We can now catch a MismatchedParentheses exception as -- MismatchedParentheses, SomeFrontendException or -- SomeCompilerException, but not other types, e.g. -- IOException: -- --
--   *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException))
--   Caught MismatchedParentheses
--   *Main> throw MismatchedParentheses catch e -> putStrLn ("Caught " ++ show (e :: IOException))
--   *** Exception: MismatchedParentheses
--   
class (Typeable e, Show e) => Exception e toException :: Exception e => e -> SomeException fromException :: Exception e => SomeException -> Maybe e instance Typeable UpErrors instance Typeable2 UpCasting instance Typeable2 To instance Typeable ToErrors instance Typeable ZipperException instance Show (Up c b) instance Num (Up c b) instance Integral (Up c b) instance Eq (Up c b) instance Ord (Up c b) instance Bounded (Up c b) instance Enum (Up c b) instance Real (Up c b) instance Show UpErrors instance Eq UpErrors instance Show (UpCasting c b) instance Eq (UpCasting c b) instance Category To instance Show ToErrors instance Eq ToErrors instance Exception ToErrors instance Exception UpErrors instance Exception ZipperException instance Show ZipperException instance LevelDelta To instance LevelDelta Up instance Motion To instance Motion UpCasting instance Motion Up instance Category Up instance Typeable2 Zipper