transient-0.1.0.0: src/Transient/Logged.hs
-----------------------------------------------------------------------------
--
-- Module : Transient.Logged
-- Copyright :
-- License : GPL-3
--
-- Maintainer : agocorona@gmail.com
-- Stability :
-- Portability :
--
-- |
--
-----------------------------------------------------------------------------
{-# LANGUAGE ExistentialQuantification #-}
module Transient.Logged where
import Data.Typeable
import Unsafe.Coerce
import Transient.Base
import Control.Applicative
import Control.Monad.IO.Class
--data IDynamic= IDyns String | forall a.(Read a, Show a,Typeable a) => IDynamic a
--instance Show IDynamic where
-- show (IDynamic x)= show $ show x
-- show (IDyns s)= show s
--
--instance Read IDynamic where
-- readsPrec n str= map (\(x,s) -> (IDyns x,s)) $ readsPrec n str
fromIDyn :: (Read a, Show a, Typeable a) => IDynamic -> a
fromIDyn (IDynamic x)= unsafeCoerce x
fromIDyn (IDyns s)=r where r= read s !> "read " ++ s ++ "to type "++ show (typeOf r)
toIDyn x= IDynamic x
-- | synonymous of `step`
logged :: (Show a, Read a, Typeable a) => TransientIO a -> TransientIO a
logged= step
-- | write the result of the computation in the log and return it.
-- but if there is data in the internal log, it read the data from the log and
-- do not execute the computation.
--
-- It accept nested step's. The effect is that if the outer step is executed completely
-- the log of the inner steps are erased. If it is not the case, the inner steps are logged
-- this reduce the log of large computations to the minimum. That is a feature not present
-- in the package Workflow.
--
-- > r <- step $ do
-- > step this :: TransIO ()
-- > step that :: TransIO ()
-- > step thatOther
-- > liftIO $ print r
--
-- when `print` is executed, the log is just the value of r.
--
-- but when `thatOther` is executed the log is: [Exec,(), ()]
--
step :: (Show a, Read a, Typeable a) => TransientIO a -> TransientIO a
step mx= do
Log recover rs full <- getSData <|> return ( Log False [][])
case (recover,rs) of
(True, Step x: rs') -> do
setSData $ Log recover rs' full
return $ fromIDyn x !> "read in step:" ++ show x
(True,Exec:rs') -> do
setSData $ Log recover rs' full
mx
(True, WaitRemote:rs') -> do
setSData (Log recover rs' full) !> "waitRemote2"
empty
_ -> do
let add= Exec: full
setSData $ Log False add add
r <- mx
let add= Step (toIDyn r): full
setSData $ Log False add add
return r