-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Cache values to disk. -- -- The module Data.Cached lets you cache values to disk to avoid -- re-running (potentially long) computations between consecutive -- executions of your program. Cached values are recomputed only when -- needed, i.e. when other cached values on which they depend change. -- Independent computations are run in parallel. It offers convenient -- fonctions for caching to text files, but caching and uncaching using -- arbitrary IO actions is also possible. -- -- The module was motivated by writing scientific data flows, simulation -- experiments or data science scripts. Those often involve long -- computations and create "flows" where the output of some computation -- are the inputs of others, until final results are produced (values, -- figures, statistical tests, etc.). -- -- See the module Data.Cached documentation: @package cached @version 0.1.0.0 module Data.Cached.Internal -- | A value that is produced from files on disk or arbitrary IO actions. data Cached a Cached :: ExceptT Text IO a -> Set FilePath -> Build -> Cached a [cacheRead] :: Cached a -> ExceptT Text IO a [cacheNeeds] :: Cached a -> Set FilePath [cacheBuild] :: Cached a -> Build CacheFail :: Text -> Cached a newtype Build Build :: Map FilePath (ExceptT Text IO (), Set FilePath) -> Build [getBuild] :: Build -> Map FilePath (ExceptT Text IO (), Set FilePath) isBuilt :: FilePath -> Build -> Bool buildSingle :: FilePath -> ExceptT Text IO () -> Set FilePath -> Build buildList :: Build -> [(FilePath, ExceptT Text IO (), Set FilePath)] buildTargets :: Build -> [FilePath] buildShakeRules :: Build -> Rules () prettyBuild :: Build -> Text instance GHC.Base.Functor Data.Cached.Internal.Cached instance GHC.Base.Applicative Data.Cached.Internal.Cached instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Data.Cached.Internal.Cached a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Data.Cached.Internal.Cached a) instance GHC.Num.Num a => GHC.Num.Num (Data.Cached.Internal.Cached a) instance GHC.Real.Fractional a => GHC.Real.Fractional (Data.Cached.Internal.Cached a) instance GHC.Float.Floating a => GHC.Float.Floating (Data.Cached.Internal.Cached a) instance GHC.Base.Semigroup Data.Cached.Internal.Build instance GHC.Base.Monoid Data.Cached.Internal.Build -- |

Usage

-- -- A value of type "Cached a" should be understood as a value of type "a" -- that is read from a file, or that is produced from data stored in one -- or more files, or from arbitrary IO actions. -- -- Cached values can be created from pure values, -- --
--   >>> let a = cache' "/tmp/cached-ex/a" (pure 1) :: Cached Int
--   
-- -- or from files stored on disk. -- --
--   >>> let b = source' "/tmp/cached-ex/b" :: Cached Int
--   
-- -- Use the functor and applicative instances to use cached values in new -- computations. -- --
--   >>> let bigA = fmap (* 2) a
--   
--   >>> let c = (+) <$> a <*> b
--   
-- -- The cached value "c" represents a value produced by summing together -- the values stored in "/tmp/cached-ex/a" and "/tmp/cached-ex/b". It is -- not yet associated to its own cache file. To actually store it into a -- cache file, use cache' (or cache for values that are not -- instances of Show and Read or when you want to control the file -- format, e.g. writing arrays to CSV files) -- --
--   >>> let c' = cache' "/tmp/cached-ex/c" c
--   
-- -- Running the cached computation "c'" will execute all necessary -- computations and write results to files as expected: -- --
--   >>> -- Before running, let's make sure the target directory is clean.
--   
--   >>> :!mkdir -p /tmp/cached-ex
--   
--   >>> :!rm -f /tmp/cached-ex/*
--   
--   >>> :!echo 2 > /tmp/cached-ex/b
--   
--   >>> 
--   
--   >>> runShake "/tmp/cached-ex/.shake" c'
--   # Writing cache (for /tmp/cached-ex/a)
--   # Writing cache (for /tmp/cached-ex/c)
--   Build completed ...
--   ...
--   
-- -- Running it again won't run anything. Since none of the cached or -- source files have changed, there is nothing to re-compute. -- --
--   >>> runShake "/tmp/cached-ex/.shake" c'
--   Build completed ...
--   ...
--   
-- -- If we modify the content of "/tmp/cached-ex/b", running "c'" again -- will only re-run the computation for "c'", and not for "a" since it -- does not depend on "b". -- --
--   >>> :! echo 3 > /tmp/cached-ex/b
--   
--   >>> runShake "/tmp/cached-ex/.shake" c'
--   # Writing cache (for /tmp/cached-ex/c)
--   Build completed ...
--   ...
--   
-- -- The cache files and dependencies can be inspected with -- prettyCached. -- --
--   >>> prettyCached c' >>= putStr
--   Cached Value = 4
--   Cached Needs:
--     /tmp/cached-ex/c
--   Cached Build:
--     /tmp/cached-ex/a
--     /tmp/cached-ex/c
--       /tmp/cached-ex/a
--       /tmp/cached-ex/b
--   
-- -- The previous output means that the value carried by "c'" is 4, and -- that in order to be computed, it needs the file "/tmp/cached-ex/c". -- The last field, "Cached Build", lists each file that is to be built by -- the cache system and their dependencies: "/tmp/cache-ex/a" and -- "/tmp/cache-ex/c" are created by the cache system, and the latter -- depends on "/tmp/cache-ex/a" and "/tmp/cache-ex/b" -- -- To put together different independent cached values into a single one -- so that they all get built together, use <>. However, -- "Cached a" is an instance of Semigroup only if "a" is. You can "sink" -- the cached values first, which will turn a "Cache a" into a "Cache -- ()", satisfying the Semigroup constraint. -- --
--   >>> let d = sink' "/tmp/cached-ex/d" (pure 'd')
--   
--   >>> let e = sink' "/tmp/cached-ex/e" (pure 'e')
--   
--   >>> let de = d <> e
--   
--   >>> prettyCached de >>= putStr
--   Cached Value = ()
--   Cached Needs:
--   Cached Build:
--     /tmp/cached-ex/d
--     /tmp/cached-ex/e
--   
module Data.Cached -- | A value that is produced from files on disk or arbitrary IO actions. data Cached a -- | Extract the value cached value. getValue :: Cached a -> IO (Either Text a) -- | Create a cached value from an input file. source :: FilePath -> (Text -> Either Text a) -> Cached a -- | A convenient variant of source when the type of the value to be -- read instantiates Read. source' :: Read a => FilePath -> Cached a -- | Create a cached value from an IO action that depends on some input -- files. fromIO :: Set FilePath -> IO a -> Cached a -- | Associate a cached value to a file on disk. cache :: FilePath -> (a -> Text) -> (Text -> Either Text a) -> Cached a -> Cached a -- | A convenient variant of cache when the type of the value to be -- read is an instance of Read and Show. cache' :: (Show a, Read a) => FilePath -> Cached a -> Cached a -- | Caching with arbitrary IO actions. cacheIO :: FilePath -> (a -> IO ()) -> IO (Either Text a) -> Cached a -> Cached a -- | Associate a cached value to a file on disk without the possibility to -- read it back. Useful for storing to a text file the final result of a -- computation that doesn't need to be read again, like data for -- producing figures, text output, etc. sink :: FilePath -> (a -> Either Text Text) -> Cached a -> Cached () -- | A convenient variant of sink when the written value type -- instantiates Show. sink' :: Show a => FilePath -> Cached a -> Cached () -- | Sink with an arbitrary IO action. sinkIO :: FilePath -> (a -> IO (Either Text ())) -> Cached a -> Cached () -- | Trigger an IO action that depends on a set of files. For example, -- consider an executable "plot" that processes the content of a file -- "data.csv" and writes an image to "fig.png". The figure creation can -- be integrated into the cache system like so: -- --
--   >>> import System.Process (callCommand)
--   
--   >>> let t = trigger "fig.png" (return <$> callCommand "plot") (Set.fromList ["data.csv"])
--   
--   >>> prettyCached t >>= putStr
--   Cached Value = ()
--   Cached Needs:
--   Cached Build:
--     fig.png
--       data.csv
--   
trigger :: FilePath -> IO (Either Text ()) -> Set FilePath -> Cached () -- | Get shake Rules. Those can be mixed together with other shake -- rules. toShakeRules :: Cached a -> Rules () -- | Run the cached computation using shake (see shakebuild.com, -- Development.Shake). If you use the result of this function as -- your program's main, you can pass shake options as arguments. Try -- "my-program --help" runShake :: FilePath -> Cached a -> IO () prettyCached :: Show a => Cached a -> IO Text