-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A monad for rewriting things. -- -- Edit is a monad for rewriting things. @package edit @version 1.0.0.0 -- | The Edit type for working with rewriting systems, with -- associated operations. -- -- To see a high-level overview of some use cases and a detailed example, -- check the Data.Edit.Tutorial module. -- -- Usage notes: -- --
    --
  1. You probably want to import this module qualified to avoid a name -- collision with Data.Maybe's fromMaybe.
  2. --
  3. We re-export the composition operators from Control.Monad -- for convenience.
  4. --
module Data.Edit -- | The Edit type encapsulates rewriting. -- -- Since Edit is also a monad, it allows you to easily "bubble up" -- information on whether changes were made when working with nested data -- structures. This is helpful when you want to save the fact that you've -- reaching a fixed point while rewriting, instead of, say re-computing -- it after the fact using an Eq instance on the underlying -- data-type. -- -- For example, -- --
--   >>> halveEvens x = if x `mod` 2 == 0 then (Dirty $ x `div` 2) else (Clean x)
--   
--   >>> traverse halveEvens [1, 2, 3]
--   Dirty [1,1,3]
--   
--   >>> traverse halveEvens [1, 3, 5]
--   Clean [1,3,5]
--   
-- -- To support this behaviour, the Applicative and Monad -- instances have "polluting" semantics: -- --
    --
  1. pure = Clean = return.
  2. --
  3. The result of <*> is Clean if and only if both -- the arguments are Clean.
  4. --
  5. If you bind a Clean value, you may get anything depending -- on the function involved. However, if you bind a Dirty value, -- you will definitely get a Dirty value back.
  6. --
-- -- If you're familiar with the Writer monad, Edit is isomorphic to -- Writer Any (Any is Bool with (<>) = -- (||)). data Edit a -- | A value that has been modified. Dirty :: a -> Edit a -- | A value that has not been modified. Clean :: a -> Edit a -- | Extract the final value after having done some edits. -- -- Unlike Maybe's fromMaybe, this function doesn't require -- a default value for totality as both constructors have a value in -- them. fromEdit :: Edit a -> a -- | Return True iff the argument has the form Clean _. isClean :: Edit a -> Bool -- | Returns True iff the argument has the form Dirty _. isDirty :: Edit a -> Bool -- |
--   extract . fmap f = f . extract
--   
extract :: Comonad w => w a -> a -- |
--   duplicate = extend id
--   fmap (fmap f) . duplicate = duplicate . fmap f
--   
duplicate :: Comonad w => w a -> w w a -- |
--   extend f = fmap f . duplicate
--   
extend :: Comonad w => w a -> b -> w a -> w b -- | Was an edit made (is the value Dirty)? If yes, returns -- Just otherwise Nothing. -- --
--   >>> toMaybe (Clean "Good morning.")
--   Nothing
--   
--   >>> toMaybe (Dirty "Wink, wink.")
--   Just "Wink, wink."
--   
toMaybe :: Edit a -> Maybe a -- | Takes a clean value and a possibly dirty value and makes an -- Edit. -- --
--   >>> fromMaybe "Hi" Nothing
--   Clean "Hi"
--   
--   >>> defaultValue = 1000
--   
--   >>> correctedValue = Just 1024
--   
--   >>> fromMaybe defaultValue correctedValue
--   Dirty 1024
--   
fromMaybe :: a -> Maybe a -> Edit a -- | Takes a function that may dirty a value, and returns another which -- saves the default value if no modification is done. -- --
--   f `edits` x == fromMaybe x (f x)
--   
edits :: (a -> Maybe a) -> a -> Edit a -- | A Dirty value becomes a Left and a Clean value -- becomes a Right. -- -- Mnemonic: having things clean is usually the right situation to be in. toEither :: Edit a -> Either a a -- | A Left value becomes a Dirty and a Right value -- becomes a Clean. -- -- Mnemonic: having things clean is usually the right situation to be in. fromEither :: Either a a -> Edit a -- | Keep editing till the result is Clean (find the fixed point). -- --
--   >>> g x = if x >= 10 then Clean x else Dirty (x + 2)
--   
--   >>> polish g 3
--   11
--   
-- -- Conceptually, -- --
--   polish f x = last $ iterations f x
--   
polish :: (a -> Edit a) -> a -> a -- | Keep editing till the result is Clean, recording iterations. -- -- Similar to polish but gets the entire list of arguments tested -- instead of just the final result. The result is guaranteed to be -- non-empty because the first element will always be included. If the -- list is finite, the last element gives a Clean result. -- --
--   >>> g x = if x >= 10 then Clean x else Dirty (x + 2)
--   
--   >>> iterations g 3
--   [3,5,7,9,11]
--   
-- -- This can be helpful in debugging your transformation function. For -- example, -- --
--   [ (before, after)
--   | let xs = iterations f start
--   , (before, after) <- zip xs (tail xs)
--   , sanityCheck before && not (sanityCheck after))
--   ]
--   
iterations :: (a -> Edit a) -> a -> [a] -- | Dirty values are put on the left and Clean values are -- put on the right. -- --
--   partitionEdits = partitionEithers . map toEither
--   
partitionEdits :: [Edit a] -> ([a], [a]) -- | Forcibly make the value Clean. You probably do not want to use -- this function unless you're implementing some class instance for -- Edit. clean :: Edit a -> Edit a -- | Forcibly make the value Dirty. You probably do not want to use -- this function unless you're implementing some class instance for -- Edit. dirty :: Edit a -> Edit a -- | Left-to-right Kleisli composition of monads. (>=>) :: Monad m => a -> m b -> b -> m c -> a -> m c infixr 1 >=> -- | Right-to-left Kleisli composition of monads. -- (>=>), with the arguments flipped. -- -- Note how this operator resembles function composition -- (.): -- --
--   (.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
--   (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
--   
(<=<) :: Monad m => b -> m c -> a -> m b -> a -> m c infixr 1 <=< instance Data.Data.Data a => Data.Data.Data (Data.Edit.Edit a) instance Control.DeepSeq.NFData a => Control.DeepSeq.NFData (Data.Edit.Edit a) instance GHC.Generics.Generic (Data.Edit.Edit a) instance Data.Traversable.Traversable Data.Edit.Edit instance Data.Foldable.Foldable Data.Edit.Edit instance GHC.Base.Functor Data.Edit.Edit instance GHC.Read.Read a => GHC.Read.Read (Data.Edit.Edit a) instance GHC.Show.Show a => GHC.Show.Show (Data.Edit.Edit a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Edit.Edit a) instance GHC.Base.Applicative Data.Edit.Edit instance GHC.Base.Monad Data.Edit.Edit instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Edit.Edit a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Edit.Edit a) instance Control.Monad.Zip.MonadZip Data.Edit.Edit instance Data.Functor.Classes.Eq1 Data.Edit.Edit instance Data.Functor.Classes.Show1 Data.Edit.Edit instance Data.Functor.Classes.Read1 Data.Edit.Edit instance Test.QuickCheck.Arbitrary.Arbitrary1 Data.Edit.Edit instance Test.QuickCheck.Arbitrary.Arbitrary a => Test.QuickCheck.Arbitrary.Arbitrary (Data.Edit.Edit a) instance Control.Comonad.Comonad Data.Edit.Edit instance Control.Comonad.ComonadApply Data.Edit.Edit -- | A monad/comonad transformer for the Edit monad. -- -- I'm not entirely sure what this might be useful for, but it is -- provided for the sake of completeness. If you find a concrete use case -- for it, please submit a PR on Github to fix this section! module Control.Monad.Trans.Edit newtype EditT m a EditT :: m (Edit a) -> EditT m a [runEditT] :: EditT m a -> m (Edit a) mapEditT :: (m (Edit a) -> n (Edit b)) -> EditT m a -> EditT n b instance Data.Functor.Classes.Eq1 m => Data.Functor.Classes.Eq1 (Control.Monad.Trans.Edit.EditT m) instance Data.Functor.Classes.Show1 m => Data.Functor.Classes.Show1 (Control.Monad.Trans.Edit.EditT m) instance Data.Functor.Classes.Read1 m => Data.Functor.Classes.Read1 (Control.Monad.Trans.Edit.EditT m) instance (Data.Functor.Classes.Eq1 m, GHC.Classes.Eq a) => GHC.Classes.Eq (Control.Monad.Trans.Edit.EditT m a) instance (Data.Functor.Classes.Read1 m, GHC.Read.Read a) => GHC.Read.Read (Control.Monad.Trans.Edit.EditT m a) instance (Data.Functor.Classes.Show1 m, GHC.Show.Show a) => GHC.Show.Show (Control.Monad.Trans.Edit.EditT m a) instance GHC.Base.Functor m => GHC.Base.Functor (Control.Monad.Trans.Edit.EditT m) instance GHC.Base.Applicative m => GHC.Base.Applicative (Control.Monad.Trans.Edit.EditT m) instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Trans.Edit.EditT m) instance Control.Monad.Trans.Class.MonadTrans Control.Monad.Trans.Edit.EditT instance Control.Monad.IO.Class.MonadIO m => Control.Monad.IO.Class.MonadIO (Control.Monad.Trans.Edit.EditT m) instance Control.Monad.Zip.MonadZip m => Control.Monad.Zip.MonadZip (Control.Monad.Trans.Edit.EditT m) instance Data.Foldable.Foldable f => Data.Foldable.Foldable (Control.Monad.Trans.Edit.EditT f) instance Data.Traversable.Traversable f => Data.Traversable.Traversable (Control.Monad.Trans.Edit.EditT f) instance Control.Comonad.Comonad c => Control.Comonad.Comonad (Control.Monad.Trans.Edit.EditT c) instance Control.Comonad.Trans.Class.ComonadTrans Control.Monad.Trans.Edit.EditT -- | This is a short (?) tutorial describing how you can use the -- Edit module to help you with writing dataflow analysis code for -- a compiler. The example is a bit artificial for the sake of relative -- conciseness -- if you have a better suggestion, or find any mistakes, -- please let me know on the Github issue tracker. module Data.Edit.Tutorial