module Data.MLens.Ref
(
Ref
, readRef, writeRef, modRef
, fileRef, fileRef_
, logConsoleLens
, logMLens, logFile
) where
import Control.Monad
import Control.Category
import System.Directory
import Prelude hiding ((.), id)
import Data.MLens
type Ref m a = MLens m () a
readRef :: Monad m => MLens m () a -> m a
readRef k = getL k ()
writeRef :: Monad m => Ref m a -> a -> m ()
writeRef r a = setL r a ()
modRef :: Monad m => Ref m a -> (a -> a) -> m ()
k `modRef` f = modL k f ()
fileRef :: FilePath -> IO (Ref IO String)
fileRef f = liftM (justLens "" .) $ fileRef_ f
fileRef_ :: FilePath -> IO (Ref IO (Maybe String))
fileRef_ f = return $ MLens $ \() -> do
b <- doesFileExist f
if b then do
xs <- readFile f
length xs `seq` return (Just xs, wr)
else return (Nothing, wr)
where wr = maybe (doesFileExist f >>= \b -> when b (removeFile f)) (writeFile f)
logMLens :: Monad m => (a -> m ()) -> (a -> m ()) -> MLens m a a
logMLens getLog setLog = MLens $ \a -> getLog a >> return (a, \b -> setLog b >> return b)
logConsoleLens :: (Show a) => MLens IO a a
logConsoleLens = logMLens (putStrLn . ("Get: " ++) . show) (putStrLn . ("Set: " ++) . show)
logFile :: FilePath -> IO (String -> IO ())
logFile f = do
b <- doesFileExist f
when (not b) $ writeFile f ""
return $ appendFile f