chatty 0.6.4.1 → 0.8.0.1
raw patch · 23 files changed
Files
- CHANGELOG.md +23/−0
- System/Chatty/Commands.hs +0/−95
- System/Chatty/Filesystem.hs +0/−279
- System/Chatty/Misc.hs +0/−52
- System/Chatty/Spawn.hs +0/−78
- System/Chatty/Spawn/Builtins.hs +0/−37
- System/Chatty/Spawn/Overlay.hs +0/−70
- Text/Chatty/Channel/Broadcast.hs +2/−2
- Text/Chatty/Channel/Printer.hs +9/−12
- Text/Chatty/Expansion.hs +2/−3
- Text/Chatty/Expansion/History.hs +3/−4
- Text/Chatty/Expansion/Vars.hs +2/−3
- Text/Chatty/Extended/ANSI.hs +3/−6
- Text/Chatty/Extended/HTML.hs +3/−6
- Text/Chatty/Extended/Printer.hs +1/−3
- Text/Chatty/Finalizer.hs +0/−71
- Text/Chatty/Interactor.hs +21/−29
- Text/Chatty/Interactor/Templates.hs +6/−86
- Text/Chatty/Printer.hs +53/−65
- Text/Chatty/Scanner.hs +31/−44
- Text/Chatty/Scanner/Buffered.hs +7/−8
- Text/Chatty/Templates.hs +2/−2
- chatty.cabal +34/−10
+ CHANGELOG.md view
@@ -0,0 +1,23 @@+# Revision history for chatty++## 0.9.0.0 -- 2021-??-??++* Renamed DeafT to DiscardT (it had nothing to do with deafness).+* Removed many dependencies.+* runOutRedirFT and runInRedirFT are now constrained on MonadResource. +* RedirectionTarget is now a five-param class and the constraints depend on the instance. For file paths, it is MonadResource, but for DiscardO and RecordO it is relaxed to Monad (previously MonadIO for all instances).+* Same for RedirectionSource.+* The module Text.Chatty.Finalizer has been removed, including HandleCloserT and ChFinalizer. Instead, we're using MonadResource and ResourceT now.++## 0.8.0.0 -- 2021-01-04++Purged many modules from 0.7.0.0 that encouraged antipatterns and were far away from the original core idea of chatty. Affected modules.++ * System.Chatty.Commands+ * System.Chatty.Filesystem+ * System.Chatty.Misc+ * System.Chatty.Spawn+ * System.Chatty.Spawn.Builtins+ * System.Chatty.Spawn.Overlay+ + More removals will follow later.
− System/Chatty/Commands.hs
@@ -1,95 +0,0 @@-{-# LANGUAGE FlexibleInstances, Safe #-}--{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}---- | Provides in-haskell implementations for some standard functions-module System.Chatty.Commands where--import Text.Chatty.Printer-import Text.Chatty.Scanner-import Text.Chatty.Interactor-import Text.Chatty.Finalizer-import Text.Chatty.Expansion-import Control.Monad-import Control.Monad.Trans.Class-import Control.Monad.IO.Class-import System.IO-import System.Directory-import System.Posix.Files---- | Like 'cat' on the command line. Accepts a list of filenames. Simple pass-through, if none are provided.-cat :: (ChScanner m, ChPrinter m, MonadIO m,Functor m,ChFinalizer m) => [String] -> m ()-cat [] = mscanL >>= mprint-cat [f] = cat [] .<. f-cat (f:fs) = cat [f] >> cat fs---- | Like 'cat', but reverses the line order.-tac :: (ChFinalizer m,ChScanner m, ChPrinter m, MonadIO m,Functor m) => [String] -> m ()-tac [] = mscanL >>= (mprint . unlines . reverse . lines)-tac fs = cat fs .|. tac []---- | Pass-through, simultanously writing all input to a given file.-tee :: (ChScanner m, ChPrinter m, MonadIO m, Functor m) => String -> m ()-tee f = do- s <- mscanL- mprint s .>. f- mprint s---- | Prints the given string, after expanding it.-echo :: (ChPrinter m,ChExpand m) => String -> m ()-echo = mprintLn <=< expand---- | Mode for 'wc'.-data WcMode = CountChars | CountLines | CountWords---- | Count characters, lines or words of the input.-wc :: (ChScanner m, ChPrinter m, MonadIO m, Functor m) => WcMode -> m ()-wc CountChars = mscanL >>= (mprint . show . length) >> mprint "\n"-wc CountLines = mscanL >>= (mprint . show . length . lines) >> mprint "\n"-wc CountWords = mscanL >>= (mprint . show . length . words) >> mprint "\n"---- | Change to given directory.-cd :: MonadIO m => String -> m ()-cd = liftIO . setCurrentDirectory---- | Print current working directory.-pwd :: (MonadIO m,ChPrinter m) => m ()-pwd = liftIO getCurrentDirectory >>= mprintLn---- | List directory contents of the given directories (current one, if empty list).-ls :: (MonadIO m,ChPrinter m) => [String] -> m ()-ls [] = liftIO (getDirectoryContents ".") >>= (mprint . unlines)-ls [p] = do- fs <- liftIO $ getFileStatus p- when (isDirectory fs) $- liftIO (getDirectoryContents p) >>= (mprint . unlines)- when (isRegularFile fs) $- mprintLn p-ls (p:ps) = ls [p] >> ls ps---- | Filters only the first n lines of the input.-head :: (ChScanner m,ChPrinter m,MonadIO m,Functor m) => Int -> m ()-head n = mscanL >>= (mprint . unlines . take n . lines)---- | FIlters only the last n lines of the input.-tail :: (ChScanner m,ChPrinter m,MonadIO m,Functor m) => Int -> m ()-tail n = mscanL >>= (mprint . unlines . reverse . take n . reverse . lines)
− System/Chatty/Filesystem.hs
@@ -1,279 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleContexts, ExistentialQuantification, ScopedTypeVariables, Safe #-}-{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}--module System.Chatty.Filesystem where--import Control.Applicative-import Control.Arrow-import Control.Monad-import Control.Monad.State-import Control.Monad.Identity-import Data.Chatty.Atoms-import Data.List-import Data.Monoid-import qualified Data.Text.IO as TIO-import qualified Data.Text as T-import Text.Chatty.Printer-import Text.Chatty.Scanner--data FSExec a = FSSucc a- | NoPermission- | NotFound--data File m = File {- loadFun :: m (FSExec ()),- saveFun :: m (FSExec ()),- leftBehind :: String,- rightPending :: String- }-newtype Path = MultiPath [PathSpec] deriving (Eq,Ord,Show)-data PathSpec = Path PathRoot [PathSeg] deriving (Eq,Ord,Show)-data PathRoot = Absolute | Relative deriving (Eq,Ord,Show)-data PathSeg = SelParent | SelChild String deriving (Eq,Ord,Show)-type FileA m = Atom (File m)--data Mountpoint m = forall a. Mount {- subMounts :: [Mountpoint m],- mstate :: Atom a,- mpath :: Path,- mopen :: Path -> (Atom a, Path) -> m (FSExec (FileA m))- }--class Monad m => ChFilesystem m where- fopen :: Path -> m (FSExec (FileA m))- fpwd :: m Path- fcd :: Path -> m ()--class Monad m => CanLoad m n where- fload :: FileA n -> m (FSExec ())--class Monad m => CanSave m n where- fsave :: FileA n -> m (FSExec ())--class Monad m => CanMount m n where- fmount :: Mountpoint n -> m ()--data FilePrinterT m a = FilePrinter { runFilePrinterT :: FileA m -> m a }-data FileScannerT m a = FileScanner { runFileScannerT :: FileA m -> m a }--instance Monad m => Monad (FilePrinterT m) where- return a = FilePrinter $ \_ -> return a- m >>= f = FilePrinter $ \d -> do a <- runFilePrinterT m d; runFilePrinterT (f a) d--instance Monad m => Monad (FileScannerT m) where- return a = FileScanner $ \_ -> return a- m >>= f = FileScanner $ \d -> do a <- runFileScannerT m d; runFileScannerT (f a) d--instance Functor f => Functor (FilePrinterT f) where- fmap f a = FilePrinter $ fmap f . runFilePrinterT a--instance (Functor m, Monad m) => Applicative (FilePrinterT m) where- (<*>) = ap- pure = return--instance Functor f => Functor (FileScannerT f) where- fmap f a = FileScanner $ fmap f . runFileScannerT a--instance (Functor m, Monad m) => Applicative (FileScannerT m) where- (<*>) = ap- pure = return--instance MonadTrans FilePrinterT where- lift m = FilePrinter $ \_ -> m--instance MonadTrans FileScannerT where- lift m = FileScanner $ \_ -> m--instance MonadIO m => MonadIO (FilePrinterT m) where- liftIO = lift . liftIO--instance MonadIO m => MonadIO (FileScannerT m) where- liftIO = lift . liftIO--instance ChAtoms m => ChPrinter (FilePrinterT m) where- mprint s = FilePrinter $ \d -> do- f <- getAtom d- putAtom d f{leftBehind=reverse (take (length s) $ rightPending f) ++ leftBehind f, rightPending=drop (length s) $ rightPending f}--instance ChAtoms m => ChScanner (FileScannerT m) where- mscan1 = FileScanner $ \d -> do- f <- getAtom d- putAtom d f{leftBehind=head (rightPending f) : leftBehind f, rightPending=tail $ rightPending f}- return $ head $ rightPending f- mscanL = FileScanner $ liftM rightPending . getAtom- mscannable = FileScanner $ liftM (not . null . rightPending) . getAtom- mready = mscannable--newtype NullFsT m a = NullFs { runNullFsT :: Path -> [Mountpoint (NullFsT m)] -> m (a, Path, [Mountpoint (NullFsT m)]) }--instance Monad m => Monad (NullFsT m) where- return a = NullFs $ \p ms -> return (a,p,ms)- m >>= f = NullFs $ \p ms -> do (a,p',ms') <- runNullFsT m p ms; runNullFsT (f a) p' ms'--instance Functor f => Functor (NullFsT f) where- fmap f a = NullFs $ \p ms -> fmap (\(a,p,ms) -> (f a,p,ms)) $ runNullFsT a p ms--instance (Functor m, Monad m) => Applicative (NullFsT m) where- (<*>) = ap- pure = return- -instance MonadTrans NullFsT where- lift m = NullFs $ \p ms -> do a <- m; return (a,p,ms)--instance MonadIO m => MonadIO (NullFsT m) where- liftIO = lift . liftIO--instance Monad m => ChFilesystem (NullFsT m) where- fpwd = NullFs $ \p ms -> return (p,p,ms)- fopen p = do- ap <- absPath p- p' <- NullFs $ \wd ms -> do- case filter (isPath . snd) $ map (\m -> (m,ap `cmpPath` mpath m)) ms of- [] -> return (NotFound, wd, ms)- (p:_) -> return (FSSucc p, wd, ms)- case p' of- FSSucc (Mount subs st pa op, p') -> op p' (st,pa)- NotFound -> return NotFound- fcd p = NullFs $ \_ ms -> return ((),p,ms)--instance Monad m => CanMount (NullFsT m) (NullFsT m) where- fmount m = NullFs $ \p ms -> return ((),p,m:ms)--absPath :: ChFilesystem m => Path -> m Path-absPath (MultiPath ps) =- liftM (MultiPath . concat) $- forM ps $ \(Path r ps) -> case r of- Absolute -> return [Path Absolute $ rempar ps]- Relative -> do- MultiPath wds <- fpwd- return $ do- Path Absolute wd <- wds- return $ Path Absolute $ rempar (wd++ps)- where- rempar (SelChild _:SelParent:rem) = rempar rem- rempar (a:rem) = a : rempar rem- rempar [] = []--cmpPath' :: [PathSeg] -> [PathSeg] -> Maybe [PathSeg]-cmpPath' ps [] = Just ps-cmpPath' (SelChild a:as) (SelChild b:bs) | a == b = cmpPath' as bs-cmpPath' (SelParent:as) (SelParent:bs) = cmpPath' as bs-cmpPath' _ _ = Nothing--cmpPath :: Path -> Path -> Path-cmpPath (MultiPath as) (MultiPath bs) = MultiPath $ do- Path Absolute a <- as- Path Absolute b <- bs- case a `cmpPath'` b of- Nothing -> []- Just p -> [Path Absolute p]--isPath :: Path -> Bool-isPath (MultiPath p) = not $ null p--path :: String -> Path-path [] = MultiPath []-path ps =- let took s = takeWhile (/='/') s- left s = case drop (length $ took s) s of- [] -> []- (_:cs) -> cs- subparse [] = []- subparse s = case (took s, left s) of- ([], []) -> []- ([], l) -> subparse l- ("..", l) -> SelParent : subparse l- (".", l) -> subparse l- (t, l) -> SelChild t : subparse l- in case head ps of- '/' -> MultiPath [Path Absolute $ subparse $ tail ps]- _ -> MultiPath [Path Relative $ subparse ps]--expandofs :: (ChAtoms m,ChFilesystem m) => m (Mountpoint m)-expandofs = do- a <- newAtom- putAtom a []- return $ Mount [] a (MultiPath []) $ \(MultiPath p) (sta,pa) -> do- fa <- newAtom- let ld = do- st <- getAtom sta- case filter (\(MultiPath x,_) -> not $ null $ intersect x p) st of- [] -> putAtom fa (File ld sv "" "") >> return (FSSucc ())- (_,tx):_ -> putAtom fa (File ld sv "" tx) >> return (FSSucc ())- sv = do- st <- getAtom sta- fi <- getAtom fa- case filter (\(_,(MultiPath x,_)) -> not $ null $ intersect x p) $ zip [1..] st of- [] -> do- putAtom sta ((MultiPath p,reverse (leftBehind fi)++rightPending fi) : st)- return (FSSucc ())- (i,_):_ -> do- putAtom sta (take i st ++ [(MultiPath p,reverse (leftBehind fi)++rightPending fi)] ++ drop (i+1) st)- return (FSSucc ())- putAtom fa $ File ld sv "" ""- return $ FSSucc fa--printerfs :: (ChPrinter m,ChAtoms m,ChFilesystem m) => m (Mountpoint m)-printerfs = do- a <- newAtom- putAtom a ()- return $ Mount [] a (MultiPath []) $ \p _ -> do- fa <- newAtom- let ld = return $ FSSucc ()- sv = do- fi <- getAtom fa- mprint (reverse (leftBehind fi) ++ rightPending fi)- return $ FSSucc ()- putAtom fa $ File ld sv "" ""- return $ FSSucc fa--iomapfs :: (MonadIO m,ChAtoms m) => String -> m (Mountpoint m)-iomapfs fp = do- a <- newAtom- putAtom a ()- return $ Mount [] a (MultiPath []) $ \p _ -> do- fa <- newAtom- let ld = do- tx <- liftIO $ TIO.readFile fp- putAtom fa (File ld sv "" (T.unpack tx))- return $ FSSucc ()- sv = do- f <- getAtom fa- liftIO $ TIO.writeFile fp $ T.pack (reverse (leftBehind f)++rightPending f)- return $ FSSucc ()- putAtom fa $ File ld sv "" ""- return $ FSSucc fa--mount :: (CanMount m m, ChAtoms m, ChFilesystem m) => m (Mountpoint m) -> Path -> m ()-mount mpf p = do- mp <- mpf- fmount mp{mpath=p}--withNullFs :: ChAtoms m => NullFsT m a -> m a-withNullFs m = do- (a,_,_) <- runNullFsT m (path "/") []- return a--withExpandoFs :: (ChAtoms m, ChAtoms (NullFsT m)) => NullFsT m a -> m a-withExpandoFs m = withNullFs $ do- mount expandofs (path "/")- m
− System/Chatty/Misc.hs
@@ -1,52 +0,0 @@-{-# LANGUAGE Safe #-}--{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}---- | Provides typeclasses for clocks and randomizer environments-module System.Chatty.Misc where--import Data.Time.Clock-import Data.Time.Calendar-import System.Random---- | Typeclass for all monads that know the time-class (Functor m,Monad m) => ChClock m where- -- | Get UTC Time- mutctime :: m UTCTime- -- | Get timestamp, guaranteed to grow- mgetstamp :: m NominalDiffTime- mgetstamp = fmap (flip diffUTCTime (UTCTime (fromGregorian 1970 1 1) (secondsToDiffTime 0))) mutctime--instance ChClock IO where- mutctime = getCurrentTime---- | Typeclass for all monads that may provide random numbers-class Monad m => ChRandom m where- -- | Get a single random number- mrandom :: Random r => m r- -- | Get a single random number in the given range- mrandomR :: Random r => (r,r) -> m r--instance ChRandom IO where- mrandom = randomIO- mrandomR rs = randomRIO rs-
− System/Chatty/Spawn.hs
@@ -1,78 +0,0 @@-{-# LANGUAGE Safe #-}--{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}---- | Provides a typeclass for process spawning.-module System.Chatty.Spawn where--import Text.Chatty.Finalizer-import Text.Chatty.Printer-import Text.Chatty.Scanner-import Control.Applicative-import Control.Monad-import Control.Monad.IO.Class-import System.Exit-import System.IO-import qualified System.Process as P---- | Class for all (real or pseudo) process-spawning monads.-class Monad m => ChSpawn m where- -- | Spawn process- mspw :: String -> [String] -> Either Handle String -> m (Int,String,[Handle])- -- | Accept handle as input?- mah :: String -> m Bool--instance ChSpawn IO where- mspw pn as (Left h) = do- (_, Just hout, _, ph) <- P.createProcess (P.proc pn as){- P.std_in = P.UseHandle h,- P.std_out = P.CreatePipe }- so <- hGetContents hout- ec <- P.waitForProcess ph- return (case ec of- ExitSuccess -> 0- ExitFailure i -> i,- so, [hout])- mspw pn as (Right si) = do- (ec,so,_) <- P.readProcessWithExitCode pn as si- return (case ec of- ExitSuccess -> 0- ExitFailure i -> i,- so, [])- mah = return $ return True---- | Spawn process-spawn :: (ChFinalizer m,ChScanner m,ChPrinter m, ChSpawn m,Functor m) => String -> [String] -> m Int-spawn fn as = do- ah <- mah fn- mscanh >>= \h' -> case if ah then h' else Nothing of- Nothing -> do- si <- mscanL- (i,so,hs) <- mspw fn as (Right si)- mprint so- mqfhs hs- return i- Just h -> do- (i,so,hs) <- mspw fn as (Left h)- mprint so- mqfhs hs- return i
− System/Chatty/Spawn/Builtins.hs
@@ -1,37 +0,0 @@-{-# LANGUAGE Safe #-}--{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}---- | Provides builtins for some common commands.-module System.Chatty.Spawn.Builtins (withBuiltins) where--import System.Chatty.Spawn-import System.Chatty.Spawn.Overlay---- | Use builtins if possible.-withBuiltins :: (Functor m, ChSpawn m) => SpawnOverlayT m a -> m a-withBuiltins m = fmap fst $ runSpawnOverlayT m builtins--builtins :: ChSpawn m => [(String,[String] -> String -> m (Int,String))]-builtins =- ("cat", \_ si -> return (0,si)):- []
− System/Chatty/Spawn/Overlay.hs
@@ -1,70 +0,0 @@-{-# LANGUAGE Safe #-}--{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}---- | Provides a MonadSpawn overlay that may catch specific spawn calls and handle them itself.-module System.Chatty.Spawn.Overlay where--import System.Chatty.Spawn-import Control.Applicative-import Control.Monad-import Control.Monad.Trans.Class-import Control.Monad.IO.Class-import System.IO---- | MonadSpawn overlay. Carries a map of own command implementations that are called instead of the actual ones.-newtype SpawnOverlayT m a = SpawnOverlay { runSpawnOverlayT :: [(String,[String] -> String -> m (Int,String))] -> m (a,[(String,[String] -> String -> m (Int,String))]) }--instance Monad m => Monad (SpawnOverlayT m) where- return a = SpawnOverlay $ \o -> return (a,o)- (SpawnOverlay o) >>= f = SpawnOverlay $ \s -> do (a,s') <- o s; runSpawnOverlayT (f a) s'--instance MonadTrans SpawnOverlayT where- lift m = SpawnOverlay $ \s -> do a <- m; return (a,s)--instance MonadIO m => MonadIO (SpawnOverlayT m) where- liftIO = lift . liftIO--instance Monad m => Functor (SpawnOverlayT m) where- fmap f a = SpawnOverlay $ \s -> do (a',s') <- runSpawnOverlayT a s; return (f a',s')--instance Monad m => Applicative (SpawnOverlayT m) where- (<*>) = ap- pure = return--instance ChSpawn m => ChSpawn (SpawnOverlayT m) where- mspw pn as (Right si) = SpawnOverlay $ \s ->- case pn `elem` (map fst s) of- True -> let c = snd $ head $ filter ((==pn).fst) s- in do- (r,so) <- c as si- return ((r,so,[]),s)- False -> do- r <- mspw pn as (Right si)- return (r,s)- mspw pn as (Left h) = lift $ mspw pn as (Left h)- mah pn = SpawnOverlay $ \s ->- case pn `elem` (map fst s) of- True -> return (False,s)- False -> do- ah <- mah pn- return (ah,s)
Text/Chatty/Channel/Broadcast.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, Safe #-}+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.
Text/Chatty/Channel/Printer.hs view
@@ -1,7 +1,7 @@-{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, Safe #-}+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -62,7 +62,6 @@ newtype ArchiverT c m a = Archiver { runArchiverT' :: ([(c,[String])],[c]) -> m (a,([(c,[String])],[c])) } instance Monad m => Monad (ArchiverT c m) where- return a = Archiver $ \s -> return (a,s) (Archiver r) >>= f = Archiver $ \s -> do (a,s') <- r s; runArchiverT' (f a) s' instance MonadTrans (ArchiverT c) where@@ -72,11 +71,11 @@ liftIO = lift . liftIO instance Monad m => Functor (ArchiverT c m) where- fmap f a = liftM f a+ fmap = liftM instance Monad m => Applicative (ArchiverT c m) where (<*>) = ap- pure = return+ pure a = Archiver $ \s -> return (a,s) withAssoc :: Eq b => b -> a -> (a -> a) -> [(b,a)] -> [(b,a)] withAssoc k n f [] = [(k,f n)]@@ -97,7 +96,7 @@ cthis = Archiver $ \(r,c) -> return (head c,(r,c)) runArchiverT :: (Eq c,Monad m) => c -> ArchiverT c m a -> m (a,[(c,Replayable)])-runArchiverT c = liftM (second $ map (second Replayable) . fst) . flip runArchiverT' ([],[c])+runArchiverT c = fmap (second $ map (second Replayable) . fst) . flip runArchiverT' ([],[c]) type IntArchiverT = ArchiverT Int type BoolArchiverT = ArchiverT Bool@@ -107,7 +106,6 @@ newtype FilterT c m a = Filter { runFilterT :: (c,[c]) -> m (a,[c]) } instance Monad m => Monad (FilterT c m) where- return a = Filter $ \(c,s) -> return (a,s) (Filter g) >>= f = Filter $ \(c,s) -> do (a,s') <- g (c,s); runFilterT (f a) (c,s') instance MonadTrans (FilterT c) where@@ -117,10 +115,10 @@ liftIO = lift . liftIO instance Monad m => Functor (FilterT c m) where- fmap f a = liftM f a+ fmap = liftM instance Monad m => Applicative (FilterT c m) where- pure = return+ pure a = Filter $ \(c,s) -> return (a,s) (<*>) = ap instance (Eq c,ChPrinter m) => ChPrinter (FilterT c m) where@@ -144,7 +142,6 @@ newtype JoinerT m a = Joiner { runJoinerT :: m a } instance Monad m => Monad (JoinerT m) where- return a = Joiner $ return a (Joiner j) >>= f = Joiner $ do a <- j; runJoinerT (f a) instance MonadTrans JoinerT where@@ -158,7 +155,7 @@ instance (Functor m, Monad m) => Applicative (JoinerT m) where (<*>) = ap- pure = return+ pure a = Joiner $ return a instance ChPrinter m => ChPrinter (JoinerT m) where mprint = lift . mprint@@ -169,4 +166,4 @@ cfin _ = return () cbracket _ m = m cthis = return undefined- cprint _ s = mprint s+ cprint _ = mprint
Text/Chatty/Expansion.hs view
@@ -2,7 +2,7 @@ {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -37,7 +37,6 @@ newtype NullExpanderT m a = NullExpander { runNullExpanderT :: m a } instance Monad m => Monad (NullExpanderT m) where- return = NullExpander . return (NullExpander ne) >>= f = NullExpander $ do ne' <- ne; runNullExpanderT (f ne') instance MonadTrans NullExpanderT where@@ -48,7 +47,7 @@ instance (Functor m, Monad m) => Applicative (NullExpanderT m) where (<*>) = ap- pure = return+ pure = NullExpander . return instance MonadIO m => MonadIO (NullExpanderT m) where liftIO = lift . liftIO
Text/Chatty/Expansion/History.hs view
@@ -2,7 +2,7 @@ {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -37,7 +37,6 @@ } instance Monad m => Monad (HistoryT m) where- return a = History $ \s -> return (a,s) (History h) >>= f = History $ \s -> do (a,s') <- h s; runHistoryT (f a) s' instance MonadTrans HistoryT where@@ -51,7 +50,7 @@ instance Monad m => Applicative (HistoryT m) where (<*>) = ap- pure = return+ pure a = History $ \s -> return (a,s) class Monad he => ChHistoryEnv he where mcounth :: he Int@@ -84,4 +83,4 @@ expand = lift . expand <=< expandHist withHistory :: Monad m => HistoryT m a -> m a-withHistory = liftM fst . flip runHistoryT []+withHistory = fmap fst . flip runHistoryT []
Text/Chatty/Expansion/Vars.hs view
@@ -2,7 +2,7 @@ {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -51,7 +51,6 @@ } instance Monad m => Monad (ExpanderT m) where- return a = Expander $ \vs -> return (a,vs) (Expander e) >>= f = Expander $ \vs -> do (a,vs') <- e vs; runExpanderT (f a) vs' instance MonadTrans ExpanderT where@@ -65,7 +64,7 @@ instance Monad m => Applicative (ExpanderT m) where (<*>) = ap- pure = return+ pure a = Expander $ \vs -> return (a,vs) -- | Run this function inside a blank environment. localEnvironment :: Functor m => ExpanderT m a -> m a
Text/Chatty/Extended/ANSI.hs view
@@ -1,8 +1,6 @@-{-# LANGUAGE Safe #-}- {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -37,7 +35,6 @@ newtype AnsiPrinterT m a = AnsiPrinter { runAnsiPrinterT :: [Colour] -> m (a,[Colour]) } instance Monad m => Monad (AnsiPrinterT m) where- return a = AnsiPrinter $ \s -> return (a,s) (AnsiPrinter p) >>= f = AnsiPrinter $ \s -> do (a,s') <- p s; runAnsiPrinterT (f a) s' instance MonadTrans AnsiPrinterT where@@ -47,7 +44,7 @@ fmap f a = AnsiPrinter $ \s -> do (a',s') <- runAnsiPrinterT a s; return (f a',s') instance Monad m => Applicative (AnsiPrinterT m) where- pure = return+ pure a = AnsiPrinter $ \s -> return (a,s) (<*>) = ap instance MonadIO m => MonadIO (AnsiPrinterT m) where@@ -74,7 +71,7 @@ instance (Functor m,ChExpand m) => ChExpand (AnsiPrinterT m) where expand s = AnsiPrinter $ \cx -> do- s1 <- (expand =<<) $ liftM (replay.snd) $ runRecorderT $ liftM fst $ flip runAnsiPrinterT cx $ expandClr s+ s1 <- (expand =<<) $ fmap (replay.snd) $ runRecorderT $ fmap fst $ flip runAnsiPrinterT cx $ expandClr s return (s1, cx) -- | Convert Chatty's colour intensity to ansi-terminal's one
Text/Chatty/Extended/HTML.hs view
@@ -1,8 +1,6 @@-{-# LANGUAGE Safe #-}- {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -36,7 +34,6 @@ newtype HtmlPrinterT m a = HtmlPrinter { runHtmlPrinterT :: m a } instance Monad m => Monad (HtmlPrinterT m) where- return = HtmlPrinter . return (HtmlPrinter p) >>= f = HtmlPrinter $ do p' <- p; runHtmlPrinterT (f p') instance MonadTrans HtmlPrinterT where@@ -47,7 +44,7 @@ instance (Functor m, Monad m) => Applicative (HtmlPrinterT m) where (<*>) = ap- pure = return+ pure = HtmlPrinter . return instance MonadIO m => MonadIO (HtmlPrinterT m) where liftIO = lift . liftIO@@ -63,7 +60,7 @@ efin = lift $ mprint "</span>" instance (Functor m,ChExpand m) => ChExpand (HtmlPrinterT m) where- expand = lift . expand <=< liftM (replay.snd) . runRecorderT . runHtmlPrinterT . expandClr+ expand = lift . expand <=< fmap (replay.snd) . runRecorderT . runHtmlPrinterT . expandClr -- | Convert the given character to its HTML representation. maskHtml :: Char -> String
Text/Chatty/Extended/Printer.hs view
@@ -1,8 +1,6 @@-{-# LANGUAGE Safe #-}- {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.
− Text/Chatty/Finalizer.hs
@@ -1,71 +0,0 @@-{-# LANGUAGE Safe #-}--{-- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs-- All wrongs reversed. Sharing is an act of love, not crime.- Please share Antisplice with everyone you like.-- Chatty is free software: you can redistribute it and/or modify- it under the terms of the GNU Affero General Public License as published by- the Free Software Foundation, either version 3 of the License, or- (at your option) any later version.-- Chatty is distributed in the hope that it will be useful,- but WITHOUT ANY WARRANTY; without even the implied warranty of- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the- GNU Affero General Public License for more details.-- You should have received a copy of the GNU Affero General Public License- along with Chatty. If not, see <http://www.gnu.org/licenses/>.--}---- | Provides handle-closing.-module Text.Chatty.Finalizer where--import Control.Applicative-import Control.Monad-import Control.Monad.IO.Class-import Control.Monad.Trans.Class-import System.IO---- | Class for all handle-finalizing monads. Required for file redirections.-class Monad m => ChFinalizer m where- -- | Enqueue handle- mqfh :: Handle -> m ()- -- | Enqueue list of handles- mqfhs :: [Handle] -> m ()- mqfhs = foldr ((>>) . mqfh) (return ())- -- | Finalize all queued handles- mfin :: m ()---- | Handle-closing transformer-newtype HandleCloserT m a = HandleCloser { runHandleCloserT :: [Handle] -> m (a,[Handle]) }--instance Monad m => Monad (HandleCloserT m) where- return a = HandleCloser $ \hs -> return (a,hs)- (HandleCloser m) >>= f = HandleCloser $ \hs -> do (a,hs') <- m hs; runHandleCloserT (f a) hs'--instance MonadTrans HandleCloserT where- lift m = HandleCloser $ \hs -> do a <- m; return (a,hs)--instance Monad m => Functor (HandleCloserT m) where- fmap f a = HandleCloser $ \hs -> do (a',hs') <- runHandleCloserT a hs; return (f a',hs')--instance Monad m => Applicative (HandleCloserT m) where- (<*>) = ap- pure = return--instance MonadIO m => MonadIO (HandleCloserT m) where- liftIO = lift . liftIO--instance MonadIO m => ChFinalizer (HandleCloserT m) where- mqfh h = HandleCloser $ \hs -> return ((),h:hs)- mfin = HandleCloser $ \hs -> do- sequence_ $ fmap (liftIO.hClose) hs- return ((),[])---- | Run function with handle closer-withLazyIO :: (MonadIO m,Functor m) => HandleCloserT m a -> m a-withLazyIO m = fmap fst $ runHandleCloserT (do a <- m; mfin; return a) []
Text/Chatty/Interactor.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FunctionalDependencies, TemplateHaskell, FlexibleContexts, TypeSynonymInstances, UndecidableInstances, Trustworthy #-}+{-# LANGUAGE FlexibleInstances, FunctionalDependencies, TemplateHaskell, FlexibleContexts, UndecidableInstances, Trustworthy #-} {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -29,41 +29,33 @@ import Text.Chatty.Printer import Text.Chatty.Scanner import Text.Chatty.Scanner.Buffered-import Text.Chatty.Finalizer import Text.Chatty.Expansion import Text.Chatty.Expansion.Vars import Text.Chatty.Expansion.History import Text.Chatty.Extended.HTML import Text.Chatty.Extended.ANSI import Text.Chatty.Channel.Printer-import System.Chatty.Filesystem-import System.Chatty.Misc import Text.Chatty.Interactor.Templates-import System.Chatty.Spawn-import System.Chatty.Spawn.Overlay import Control.Monad import Control.Monad.State import Control.Monad.Trans.Class import Control.Monad.Identity import System.IO -mkInteractor ''RecorderT mkScanner mkBufferedScanner mkFinalizer mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkCounter mkAtoms mkFilesys-mkInteractor ''DeafT mkScanner mkBufferedScanner mkFinalizer mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkCounter mkAtoms mkFilesys-mkInteractor ''OutRedirT mkScanner mkBufferedScanner mkFinalizer mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkCounter mkAtoms mkFilesys-mkInteractor ''HandleCloserT mkScanner mkBufferedScanner mkPrinter mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''ExpanderT mkScanner mkBufferedScanner mkPrinter mkFinalizer mkSpawn mkRandom mkClock mkHistoryEnv mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''HereStringT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''QuietT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''InRedirT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''SpawnOverlayT mkPrinter mkExtendedPrinter mkScanner mkBufferedScanner mkExpander mkExpanderEnv mkHistoryEnv mkFinalizer mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''HtmlPrinterT mkScanner mkBufferedScanner mkExpanderEnv mkHistoryEnv mkFinalizer mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''AnsiPrinterT mkScanner mkBufferedScanner mkExpanderEnv mkHistoryEnv mkFinalizer mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''NullExpanderT mkScanner mkBufferedScanner mkPrinter mkExtendedPrinter mkFinalizer mkSpawn mkRandom mkClock mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''HistoryT mkScanner mkBufferedScanner mkPrinter mkExtendedPrinter mkFinalizer mkSpawn mkRandom mkClock mkExpanderEnv mkDefCP mkCounter mkAtoms mkFilesys-mkInteractor ''ScannerBufferT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkFinalizer mkRandom mkClock mkDefCP mkSpawn mkCounter mkAtoms mkFilesys-mkInteractor ''NullFsT mkScanner mkPrinter mkBufferedScanner mkFinalizer mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkCounter mkAtoms mkDefCP mkExtendedPrinter-mkInteractor ''CounterT mkScanner mkPrinter mkBufferedScanner mkFinalizer mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkDefCP mkExtendedPrinter-mkInteractor ''AtomStoreT mkScanner mkPrinter mkBufferedScanner mkFinalizer mkExpander mkExpanderEnv mkHistoryEnv mkSpawn mkRandom mkClock mkDefCP mkExtendedPrinter+mkInteractor ''RecorderT mkScanner mkBufferedScanner mkExpander mkExpanderEnv mkHistoryEnv mkCounter mkAtoms +mkInteractor ''DiscardT mkScanner mkBufferedScanner mkExpander mkExpanderEnv mkHistoryEnv mkCounter mkAtoms +mkInteractor ''OutRedirT mkScanner mkBufferedScanner mkExpander mkExpanderEnv mkHistoryEnv mkCounter mkAtoms +mkInteractor ''ExpanderT mkScanner mkBufferedScanner mkPrinter mkHistoryEnv mkDefCP mkCounter mkAtoms +mkInteractor ''HereStringT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkDefCP mkCounter mkAtoms +mkInteractor ''QuietT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkDefCP mkCounter mkAtoms +mkInteractor ''InRedirT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkDefCP mkCounter mkAtoms +mkInteractor ''HtmlPrinterT mkScanner mkBufferedScanner mkExpanderEnv mkHistoryEnv mkDefCP mkCounter mkAtoms +mkInteractor ''AnsiPrinterT mkScanner mkBufferedScanner mkExpanderEnv mkHistoryEnv mkDefCP mkCounter mkAtoms +mkInteractor ''NullExpanderT mkScanner mkBufferedScanner mkPrinter mkExtendedPrinter mkDefCP mkCounter mkAtoms +mkInteractor ''HistoryT mkScanner mkBufferedScanner mkPrinter mkExtendedPrinter mkExpanderEnv mkDefCP mkCounter mkAtoms +mkInteractor ''ScannerBufferT mkPrinter mkExtendedPrinter mkExpander mkExpanderEnv mkHistoryEnv mkDefCP mkCounter mkAtoms+mkInteractor ''CounterT mkScanner mkPrinter mkBufferedScanner mkExpander mkExpanderEnv mkHistoryEnv mkDefCP mkExtendedPrinter+mkInteractor ''AtomStoreT mkScanner mkPrinter mkBufferedScanner mkExpander mkExpanderEnv mkHistoryEnv mkDefCP mkExtendedPrinter mkInteractor ''IntArchiverT mkArchiver mkInteractor ''BoolArchiverT mkArchiver mkInteractor ''HandleArchiverT mkArchiver@@ -73,7 +65,7 @@ mkInteractor ''JoinerT mkArchiver -- | IgnorantT ignores all output and does not provide any input.-type IgnorantT m = QuietT (DeafT m)+type IgnorantT m = QuietT (DiscardT m) -- | Ignorant is IgnorantT on the identity type Ignorant = IgnorantT Identity -- | ChattyT simulates a console, actually taking input as a string and recording output.@@ -83,14 +75,14 @@ -- | Run IgnorantT (does not take anything) runIgnorantT :: Monad m => IgnorantT m a -> m a-runIgnorantT = runDeafT . runQuietT+runIgnorantT = runDiscardT . runQuietT -- | Run Ignorant (does not take anything) runIgnorant :: Ignorant a -> a runIgnorant = runIdentity . runIgnorantT -- | Run ChattyT. Takes input as a string and returns (result, remaining input, output).-runChattyT :: (Monad m,Functor m) => ChattyT m a -> String -> m (a,String,Replayable)+runChattyT :: Monad m => ChattyT m a -> String -> m (a,String,Replayable) runChattyT m input = fmap (\((a,u),r) -> (a,u,r)) $ runRecorderT $ runHereStringT m input -- | Run Chatty. Takes input as a string and returns (result, remaining input, output).@@ -99,13 +91,13 @@ -- Shell-like syntax -- | Connect the output of some function to the input of another one. Compare with a pipe (cmd1 | cmd2).-(.|.) :: (Monad m,Functor m) => RecorderT m a -> HereStringT m b -> m b+(.|.) :: Monad m => RecorderT m a -> HereStringT m b -> m b m1 .|. m2 = do (_,r) <- runRecorderT m1 fmap fst $ runHereStringT m2 (replay r) -- | Runs the second function and feeds its output as an argument to the first one. Compare with process expansion ($(cmd)).-(.<$.) :: (Functor m,Monad m) => (String -> m b) -> RecorderT m a -> m b+(.<$.) :: Monad m => (String -> m b) -> RecorderT m a -> m b m1 .<$. m2 = do (_,r) <- runRecorderT m2 m1 $ replay r
Text/Chatty/Interactor/Templates.hs view
@@ -2,7 +2,7 @@ {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -22,27 +22,23 @@ -} -- | Declares serveral templates for comfortable instance derivation-module Text.Chatty.Interactor.Templates (mkScanner, mkPrinter, mkFinalizer, mkExpander,mkExpanderEnv,mkHistoryEnv,mkInteractor,mkSpawn,mkRandom,mkClock,mkChatty,mkChannelPrinter,mkDefCP,mkArchiver,mkExtendedPrinter,mkBufferedScanner,mkCounter,mkAtoms,mkFilesys) where+module Text.Chatty.Interactor.Templates (mkScanner, mkPrinter, mkExpander,mkExpanderEnv,mkHistoryEnv,mkInteractor,mkChatty,mkChannelPrinter,mkDefCP,mkArchiver,mkExtendedPrinter,mkBufferedScanner,mkCounter,mkAtoms) where import Data.Chatty.Atoms import Data.Chatty.Counter import Text.Chatty.Scanner import Text.Chatty.Scanner.Buffered import Text.Chatty.Printer-import Text.Chatty.Finalizer import Text.Chatty.Expansion import Text.Chatty.Expansion.Vars import Text.Chatty.Expansion.History import Text.Chatty.Channel.Printer import Text.Chatty.Channel.Broadcast-import System.Chatty.Spawn-import System.Chatty.Filesystem import Text.Chatty.Extended.Printer import Control.Monad import Control.Monad.Trans import Language.Haskell.TH import Text.Chatty.Templates-import System.Chatty.Misc import System.IO -- | Automatically derives a ChScanner instance for you.@@ -100,35 +96,10 @@ where sx = strToType s cx = strToType c -{-- | Automatically derives a Broadcaster instance for you.-mkBroadcaster :: Name -> Name -> Q [Dec]-mkBroadcaster c s = [d|- instance Broadcaster $cx m => Broadcaster $cx ($sx m) where- bprint b = lift . bprint (lift . b)- instance BroadcasterBracket $cx m => BroadcasterBracket $cx ($sx m) where- bstart b = lift $ bstart (lift . b)- bfin b = lift $ bfin (lift . b)- |]- where sx = strToType s- cx = strToType c-}- -- | Automatically derives ChChannelPrinter instances for 'Int', 'Bool' and 'Handle' channels. mkDefCP :: Name -> Q [Dec] mkDefCP s = mkInteractor s (mkChannelPrinter ''Int) (mkChannelPrinter ''Bool) (mkChannelPrinter ''Handle) -{-- | Automatically derives Broadcaster instances for 'Int', 'Bool' and 'Handle' channels-mkDefBC :: Name -> Q [Dec]-mkDefBC s = mkInteractor s (mkBroadcaster ''Int) (mkBroadcaster ''Bool) (mkBroadcaster ''Handle)-}---- | Automatically derives a ChFinalizer instance for you.-mkFinalizer :: Name -> Q [Dec]-mkFinalizer s = [d|- instance ChFinalizer m => ChFinalizer ($sx m) where- mqfh = lift . mqfh- mfin = lift mfin- |] - where sx = strToType s- -- | Automatically derives a ChExpand instance for you. mkExpander :: Name -> Q [Dec] mkExpander s = [d|@@ -156,33 +127,6 @@ |] where sx = strToType s --- | Automatically derives a ChSpawn instance for you.-mkSpawn :: Name -> Q [Dec]-mkSpawn s = [d|- instance ChSpawn m => ChSpawn ($sx m) where- mspw pn as si = lift $ mspw pn as si- mah = lift . mah- |]- where sx = strToType s---- | Automatically derives a ChRandom instance for you.-mkRandom :: Name -> Q [Dec]-mkRandom s = [d|- instance ChRandom m => ChRandom ($sx m) where- mrandom = lift mrandom- mrandomR = lift . mrandomR- |] - where sx = strToType s---- | Automatically derives a ChClock instance for you.-mkClock :: Name -> Q [Dec]-mkClock s = [d|- instance ChClock m => ChClock ($sx m) where- mutctime = lift mutctime- mgetstamp = lift mgetstamp- |] - where sx = strToType s- -- | Automatically derives a ChCounter instance for you. mkCounter :: Name -> Q [Dec] mkCounter s = [d|@@ -200,45 +144,21 @@ dispAtom = lift . dispAtom |] where sx = strToType s---- | Automatically derives instances for ChFilesystem, CanLoad, CanSave, CanMount.-mkFilesys :: Name -> Q [Dec]-mkFilesys s = [d|- instance (ChAtoms ($sx m), ChFilesystem m) => ChFilesystem ($sx m) where- fopen p = do- res <- lift $ fopen p- case res of- NoPermission -> return NoPermission- NotFound -> return NotFound- FSSucc a -> liftM FSSucc $ funAtom a (\a -> File (lift $ loadFun a) (lift $ saveFun a) (leftBehind a) (rightPending a)) (\b a -> b{leftBehind=leftBehind a,rightPending=rightPending a})- fpwd = lift fpwd- fcd = lift . fcd- instance CanLoad m n => CanLoad ($sx m) n where- fload = lift . fload- instance CanSave m n => CanSave ($sx m) n where- fsave = lift . fsave- instance CanMount m n => CanMount ($sx m) n where- fmount = lift . fmount- |]- where sx = strToType s -- | Automatically derives all chatty typeclasses for you. mkChatty :: Name -> Q [Dec] mkChatty s = mkInteractor s- mkPrinter mkScanner mkFinalizer mkExpander- mkSpawn mkRandom mkClock mkExpanderEnv+ mkPrinter mkScanner mkExpander+ mkExpanderEnv mkHistoryEnv mkDefCP mkExtendedPrinter mkBufferedScanner mkCounter mkAtoms- mkFilesys--- mkDefBC -- | Automatically derives all chatty typeclasses that are sensible for an ArchiverT. mkArchiver :: Name -> Q [Dec] mkArchiver s = mkInteractor s mkScanner mkExpander mkExpanderEnv- mkHistoryEnv mkFinalizer mkSpawn- mkRandom mkClock mkCounter mkAtoms- mkFilesys+ mkHistoryEnv+ mkCounter mkAtoms -- | Just a helper class for mkInteractor class InteractorMaker i where
Text/Chatty/Printer.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, Safe #-}+{-# LANGUAGE FlexibleInstances, FunctionalDependencies, ConstraintKinds, KindSignatures #-} {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -29,7 +29,10 @@ import Control.Monad import Control.Monad.State import Control.Monad.Identity+import Control.Monad.Writer+import Control.Monad.Trans.Resource import System.IO+import Data.Kind -- | A typeclass for all monads that may output strings. class Monad m => ChPrinter m where@@ -50,103 +53,95 @@ mnoecho _ = return () mflush = hFlush stdout -instance Monad m => ChPrinter (StateT String m) where- mprint s = modify (++s)---- | DeafT discards all output (much like >\/dev\/null in the shell)-newtype DeafT m a = Deaf { runDeafT :: m a }+-- | DiscardT discards all output (much like >\/dev\/null in the shell)+newtype DiscardT m a = Discard { runDiscardT :: m a } -instance Monad m => Monad (DeafT m) where- return = Deaf . return- (Deaf d) >>= f = Deaf $ do d' <- d; runDeafT (f d')+instance Monad m => Monad (DiscardT m) where+ (Discard d) >>= f = Discard $ do d' <- d; runDiscardT (f d') -instance MonadTrans DeafT where- lift = Deaf+instance MonadTrans DiscardT where+ lift = Discard -instance (Functor m, Monad m) => Applicative (DeafT m) where- pure = return+instance (Functor m, Monad m) => Applicative (DiscardT m) where+ pure = Discard . return (<*>) = ap -instance Functor m => Functor (DeafT m) where- fmap f (Deaf a) = Deaf $ fmap f a+instance Functor m => Functor (DiscardT m) where+ fmap f (Discard a) = Discard $ fmap f a -instance MonadIO m => MonadIO (DeafT m) where+instance MonadIO m => MonadIO (DiscardT m) where liftIO = lift . liftIO -instance Monad m => ChPrinter (DeafT m) where+instance Monad m => ChPrinter (DiscardT m) where mprint _ = return () -- Definition of OutRedirT + instances -- | Redirects all output to a given handle (much like >filename in the shell)-newtype OutRedirT m a = OutRedir { runOutRedirT' :: Handle -> m (a,Handle) }+newtype OutRedirT m a = OutRedir { runOutRedirT :: Handle -> m a } -- | 'OutRedirT' on a blank 'IO' monad type OutRedir = OutRedirT IO instance Monad m => Monad (OutRedirT m) where- return a = OutRedir $ \h -> return (a,h)- (OutRedir r) >>= f = OutRedir $ \h -> do (a,h') <- r h; runOutRedirT' (f a) h'+ (OutRedir r) >>= f = OutRedir $ \h -> do a <- r h; runOutRedirT (f a) h instance MonadTrans OutRedirT where- lift m = OutRedir $ \h -> do a <- m; return (a,h)+ lift m = OutRedir $ \_ -> m instance MonadIO m => MonadIO (OutRedirT m) where liftIO = lift . liftIO instance MonadIO m => ChPrinter (OutRedirT m) where- mprint s = OutRedir $ \h -> do liftIO $ hPutStr h s; return ((),h)- mflush = OutRedir $ \h -> do liftIO $ hFlush h; return ((),h)+ mprint s = OutRedir $ \h -> do liftIO $ hPutStr h s; return ()+ mflush = OutRedir $ \h -> do liftIO $ hFlush h; return () instance Monad m => Functor (OutRedirT m) where- fmap f a = OutRedir $ \h -> do (a',h') <- runOutRedirT' a h; return (f a',h')+ fmap f a = OutRedir $ \h -> do a' <- runOutRedirT a h; return (f a') instance Monad m => Applicative (OutRedirT m) where- pure = return+ pure a = OutRedir $ \h -> return a (<*>) = ap --- | Run 'OutRedirT' with a 'Handle'-runOutRedirT :: Functor m => OutRedirT m a -> Handle -> m a-runOutRedirT m h = fmap fst $ runOutRedirT' m h+instance MonadResource m => MonadResource (OutRedirT m) where+ liftResourceT = lift . liftResourceT -- | Run 'OutRedir' with a 'Handle' runOutRedir :: OutRedir a -> Handle -> IO a runOutRedir = runOutRedirT -- | Run 'OutRedirT' with a 'FilePath'-runOutRedirFT :: (Functor m,MonadIO m) => OutRedirT m a -> FilePath -> IOMode -> m a+runOutRedirFT :: MonadResource m => OutRedirT m a -> FilePath -> IOMode -> m a runOutRedirFT m fp md | md `elem` [AppendMode,WriteMode] = do- h <- liftIO $ openFile fp md- a <- runOutRedirT m h- liftIO $ hClose h- return a+ (key, h) <- allocate (liftIO $ openFile fp md) (liftIO . hClose)+ a <- runOutRedirT m h+ a `seq` release key+ return a | otherwise = error "runOutRedirFT does only accept AppendMode or WriteMode." --- | Run 'OutRedir' with a 'FilePath'-runOutRedirF :: OutRedir a -> FilePath -> IOMode -> IO a-runOutRedirF = runOutRedirFT- -- Definition of RecorderT + instances -- | Catches all output (much like VAR=$(...) in the shell)-newtype RecorderT m a = Recorder { runRecorderT' :: [String] -> m (a,[String]) }+newtype RecorderT m a = Recorder { runRecorderT' :: m (a,[String]) } -- | 'RecorderT' on the 'Identity' type Recorder = RecorderT Identity instance Monad m => Monad (RecorderT m) where- return a = Recorder $ \s -> return (a,s)- (Recorder r) >>= f = Recorder $ \s -> do (a,s') <- r s; runRecorderT' (f a) s'+ (Recorder r) >>= f = Recorder $ do+ (a,s) <- r+ (a',s') <- runRecorderT' (f a)+ return (a', s'++s) instance MonadTrans RecorderT where- lift m = Recorder $ \s -> do a <- m; return (a,s)+ lift m = Recorder $ do a <- m; return (a,[]) instance Monad m => ChPrinter (RecorderT m) where- mprint s = Recorder $ \s' -> return ((),s:s')+ mprint s = Recorder $ return ((),[s]) instance Monad m => Functor (RecorderT m) where- fmap f a = Recorder $ \s -> do (a',s') <- runRecorderT' a s; return (f a',s')+ fmap = liftM instance Monad m => Applicative (RecorderT m) where (<*>) = ap- pure = return+ pure a = Recorder $ return (a,[]) instance MonadIO m => MonadIO (RecorderT m) where liftIO = lift . liftIO@@ -154,27 +149,20 @@ -- Helper methods for RecorderT -- | The recorder state. Use this together with 'replay', 'replayM' or 'replay_'. newtype Replayable = Replayable [String]-instance Show Replayable where show r = show ((\(Replayable x) -> length x) r) ++ ":" ++ show (replay r)---- | Replay a recorder state inside a 'Monad'.-replayM :: Monad m => m Replayable -> m String-replayM r = do (Replayable r') <- r; return (concat $ reverse r')+instance Show Replayable where+ show r = show ((\(Replayable x) -> length x) r) ++ ":" ++ show (replay r) -- | Replay a recorder state in a pure context. replay :: Replayable -> String replay (Replayable r) = concat $ reverse r --- | Replay the current recorder state without leaving the recorder.-replay_ :: Monad m => RecorderT m String-replay_ = Recorder $ \s -> return (concat $ reverse s,s)- -- | Run 'Recorder' and also return its state. runRecorder :: Recorder a -> (a,Replayable)-runRecorder = second Replayable . runIdentity . flip runRecorderT' []+runRecorder = second Replayable . runIdentity . runRecorderT' -- | Run 'RecorderT' and also return its state.-runRecorderT :: (Functor m,Monad m) => RecorderT m a -> m (a,Replayable)-runRecorderT = fmap (second Replayable) . flip runRecorderT' []+runRecorderT :: Monad m => RecorderT m a -> m (a,Replayable)+runRecorderT = fmap (second Replayable) . runRecorderT' -- | Line-terminating alternative to 'mprint' mprintLn :: ChPrinter m => String -> m ()@@ -190,18 +178,18 @@ -- | Redirection target that records input. data RecordO = RecordO -- | Class for all redirection targets.-class RedirectionTarget t mt a r | t -> mt, t a -> r where+class RedirectionTarget t (c :: (* -> *) -> Constraint) mt a r | t -> mt c, t a -> r where -- | Overwriting redirection.- (.>.) :: (Functor m,MonadIO m,ChPrinter (mt m)) => mt m a -> t -> m r+ (.>.) :: (c m,ChPrinter (mt m)) => mt m a -> t -> m r -- | Appending redirection.- (.>>.) :: (Functor m,MonadIO m,ChPrinter (mt m)) => mt m a -> t -> m r+ (.>>.) :: (c m,ChPrinter (mt m)) => mt m a -> t -> m r (.>>.) = (.>.)-instance RedirectionTarget DiscardO DeafT a a where- m .>. _ = runDeafT m-instance RedirectionTarget RecordO RecorderT a (a,Replayable) where+instance RedirectionTarget DiscardO Monad DiscardT a a where+ m .>. _ = runDiscardT m+instance RedirectionTarget RecordO Monad RecorderT a (a,Replayable) where m .>. _ = runRecorderT m-instance RedirectionTarget FilePath OutRedirT a a where+instance RedirectionTarget FilePath MonadResource OutRedirT a a where m .>. fp = runOutRedirFT m fp WriteMode m .>>. fp = runOutRedirFT m fp AppendMode-instance RedirectionTarget Handle OutRedirT a a where+instance RedirectionTarget Handle MonadIO OutRedirT a a where m .>. fp = runOutRedirT m fp
Text/Chatty/Scanner.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, Safe #-}+{-# LANGUAGE FlexibleInstances, FunctionalDependencies, ConstraintKinds, KindSignatures #-} {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -24,13 +24,14 @@ -- | Provides a typeclass for all monads that may scan text. module Text.Chatty.Scanner where -import Text.Chatty.Finalizer import Control.Applicative import Control.Monad import Control.Monad.State import Control.Monad.Identity import Control.Monad.Trans.Class+import Control.Monad.Trans.Resource import System.IO+import Data.Kind -- | A typeclass for all monads that may read input. class Monad m => ChScanner m where@@ -73,7 +74,6 @@ newtype HereStringT m a = HereString { runHereStringT :: String -> m (a,String) } instance Monad m => Monad (HereStringT m) where- return a = HereString $ \s -> return (a,s) (HereString h) >>= f = HereString $ \s -> do (a,s') <- h s; runHereStringT (f a) s' instance MonadTrans HereStringT where@@ -84,7 +84,7 @@ instance Monad m => Applicative (HereStringT m) where (<*>) = ap- pure = return+ pure a = HereString $ \s -> return (a,s) instance Monad m => ChScanner (HereStringT m) where mscan1 = HereString $ \(s:ss) -> return (s,ss)@@ -95,16 +95,14 @@ instance MonadIO m => MonadIO (HereStringT m) where liftIO = lift . liftIO -instance ChFinalizer m => ChFinalizer (HereStringT m) where- mqfh = lift . mqfh- mfin = lift mfin+instance MonadResource m => MonadResource (HereStringT m) where+ liftResourceT = lift . liftResourceT -- Definition of QuietT + instances -- | QuietT does not convey any input (much like </dev/null in the shell) newtype QuietT m a = Quiet { runQuietT :: m a } instance Monad m => Monad (QuietT m) where- return = Quiet . return (Quiet q) >>= f = Quiet $ do q' <- q; runQuietT (f q') instance MonadTrans QuietT where@@ -119,65 +117,54 @@ instance Functor m => Functor (QuietT m) where fmap f (Quiet a) = Quiet $ fmap f a -instance (Functor m, Monad m) => Applicative (QuietT m) where+instance Monad m => Applicative (QuietT m) where (<*>) = ap- pure = return+ pure = Quiet . return -- Definition of InRedirT + instances -- | InRedirT redirects all input to a given handle (much like <filename in the shell)-newtype InRedirT m a = InRedir { runInRedirT' :: Handle -> m (a,Handle) }+newtype InRedirT m a = InRedir { runInRedirT :: Handle -> m a } -- | InRedirT on an IO monad-type InRedir = InRedirT (HandleCloserT IO)+type InRedir = InRedirT IO instance Monad m => Monad (InRedirT m) where- return a = InRedir $ \h -> return (a,h)- (InRedir r) >>= f = InRedir $ \h -> do (a,h') <- r h; runInRedirT' (f a) h'+ (InRedir r) >>= f = InRedir $ \h -> do a <- r h; runInRedirT (f a) h instance MonadTrans InRedirT where- lift m = InRedir $ \h -> do a <- m; return (a,h)+ lift m = InRedir $ \_ -> m instance MonadIO m => MonadIO (InRedirT m) where liftIO = lift . liftIO instance MonadIO m => ChScanner (InRedirT m) where- mscan1 = InRedir $ \h -> do c <- liftIO $ hGetChar h; return (c,h)- mscanL = InRedir $ \h -> do s <- liftIO $ hGetContents h; return (s,h)- mscannable = InRedir $ \h -> do b <- liftIO $ hIsEOF h; return (b,h)- mscanh = InRedir $ \h -> return (Just h,h)- mready = InRedir $ \h -> do r <- liftIO $ hReady h; return (r,h)+ mscan1 = InRedir $ \h -> liftIO (hGetChar h)+ mscanL = InRedir $ \h -> liftIO (hGetContents h)+ mscannable = InRedir $ \h -> liftIO (hIsEOF h)+ mscanh = InRedir $ \h -> return (Just h)+ mready = InRedir $ \h -> liftIO (hReady h) instance Monad m => Functor (InRedirT m) where- fmap f a = InRedir $ \h -> do (a',h') <- runInRedirT' a h; return (f a',h')+ fmap f a = InRedir $ \h -> do a' <- runInRedirT a h; return (f a') instance Monad m => Applicative (InRedirT m) where (<*>) = ap- pure = return--instance ChFinalizer m => ChFinalizer (InRedirT m) where- mqfh = lift . mqfh- mfin = lift mfin+ pure a = InRedir $ \h -> return a --- | Run InRedirT with handle-runInRedirT :: Functor m => InRedirT m a -> Handle -> m a-runInRedirT m h = fmap fst $ runInRedirT' m h+instance MonadResource m => MonadResource (InRedirT m) where+ liftResourceT = lift . liftResourceT -- | Run InRedir with handle runInRedir :: InRedir a -> Handle -> IO a-runInRedir m h = withLazyIO $ runInRedirT m h+runInRedir m h = runInRedirT m h -- | Run InRedirT with a filename-runInRedirFT :: (Functor m,MonadIO m,ChFinalizer m) => InRedirT m a -> FilePath -> m a+runInRedirFT :: (Functor m,MonadResource m) => InRedirT m a -> FilePath -> m a runInRedirFT m fp = do- h <- liftIO $ openFile fp ReadMode+ (key, h) <- allocate (liftIO $ openFile fp ReadMode) (liftIO . hClose) a <- runInRedirT m h- mqfh h- --liftIO $ hClose h+ a `seq` release key return a --- | Run InRedir with a filename-runInRedirF :: InRedir a -> FilePath -> IO a-runInRedirF m fp = withLazyIO $ runInRedirFT m fp- -- | Line-scanning alternative to mscan1/L mscanLn :: ChScanner m => m String mscanLn = do@@ -203,14 +190,14 @@ -- | Redirection source that does not provide any output data EmptyI = EmptyI -- | Class for all primitive redirection sources.-class RedirectionSource t mt a r | t -> mt, t a -> r where+class RedirectionSource t (c :: (* -> *) -> Constraint) mt a r | t -> mt c, t a -> r where -- | Redirection- (.<.) :: (ChFinalizer m,Functor m,MonadIO m,ChScanner (mt m)) => mt m a -> t -> m r-instance RedirectionSource EmptyI QuietT a a where+ (.<.) :: (c m,ChScanner (mt m)) => mt m a -> t -> m r+instance RedirectionSource EmptyI Monad QuietT a a where m .<. _ = runQuietT m-instance RedirectionSource FilePath InRedirT a a where+instance RedirectionSource FilePath MonadResource InRedirT a a where m .<. fp = runInRedirFT m fp-instance RedirectionSource Handle InRedirT a a where+instance RedirectionSource Handle MonadIO InRedirT a a where m .<. fp = runInRedirT m fp -- | Class for all Here-Documents class RedirectionHeredoc t mt a r | t -> mt, t a -> r where
Text/Chatty/Scanner/Buffered.hs view
@@ -1,8 +1,8 @@-{-# LANGUAGE FlexibleInstances, Safe #-}+{-# LANGUAGE FlexibleInstances #-} {- This module is part of Chatty.- Copyleft (c) 2014 Marvin Cohrs+ Copyleft (c) 2014,2021,2026 Enum Cohrs All wrongs reversed. Sharing is an act of love, not crime. Please share Antisplice with everyone you like.@@ -57,7 +57,6 @@ newtype ScannerBufferT m a = ScannerBuffer { runScannerBufferT :: [String] -> m (a,[String]) } instance Monad m => Monad (ScannerBufferT m) where- return a = ScannerBuffer $ \s -> return (a,s) (ScannerBuffer c) >>= f = ScannerBuffer $ \s -> do (a,s') <- c s; runScannerBufferT (f a) s' instance MonadTrans ScannerBufferT where@@ -68,20 +67,20 @@ instance Monad m => Applicative (ScannerBufferT m) where (<*>) = ap- pure = return+ pure a = ScannerBuffer $ \s -> return (a,s) instance ChScanner m => ChScanner (ScannerBufferT m) where- mscan1 = ScannerBuffer $ \(ss:sx) -> (if null ss then do s <- mscan1; return (s,[]:map (s:) sx) else return (head ss,tail ss:map (head ss:) sx))+ mscan1 = ScannerBuffer $ \(ss:sx) -> if null ss then do s <- mscan1; return (s,[]:map (s:) sx) else return (head ss,tail ss:map (head ss:) sx) mscanL = ScannerBuffer $ \(ss:sx) -> do l <- mscanL; return (ss++l, []:map (++l) sx)- mscannable = ScannerBuffer $ \(ss:sx) -> (if null ss then do b <- mscannable; return (b,[]:sx) else return (True,ss:sx))+ mscannable = ScannerBuffer $ \(ss:sx) -> if null ss then do b <- mscannable; return (b,[]:sx) else return (True,ss:sx) mscanh = return Nothing- mready = ScannerBuffer $ \(ss:sx) -> (if null ss then do b <- mready; return (b,[]:sx) else return (True,ss:sx))+ mready = ScannerBuffer $ \(ss:sx) -> if null ss then do b <- mready; return (b,[]:sx) else return (True,ss:sx) instance MonadIO m => MonadIO (ScannerBufferT m) where liftIO = lift . liftIO instance ChScanner m => ChBufferedScanner (ScannerBufferT m) where- mpeek1 = ScannerBuffer $ \(ss:sx) -> (if null ss then do s <- mscan1; return (s,[s]:sx) else return (head ss,ss:sx))+ mpeek1 = ScannerBuffer $ \(ss:sx) -> if null ss then do s <- mscan1; return (s,[s]:sx) else return (head ss,ss:sx) mprepend s = ScannerBuffer $ \(ss:sx) -> return ((),(s++ss):sx) instance ChScanner m => ChStackBufferedScanner (ScannerBufferT m) where
Text/Chatty/Templates.hs view
@@ -30,8 +30,8 @@ strToType s = do TyConI d <- reify s case d of- DataD _ n _ _ _ -> conT $ simpleName n- NewtypeD _ n _ _ _ -> conT $ simpleName n+ DataD _ n _ _ _ _ -> conT $ simpleName n+ NewtypeD _ n _ _ _ _ -> conT $ simpleName n TySynD n _ _ -> conT $ simpleName n where simpleName :: Name -> Name
chatty.cabal view
@@ -10,14 +10,15 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.6.4.1+version: 0.8.0.1 -- A short (one-line) description of the package.-synopsis: Some monad transformers and typeclasses for abstraction of global dependencies.+synopsis: Some monad transformers and typeclasses for text in- and output abstraction. -- A longer description of the package.-description: Some monad transformers and typeclasses abstracting global dependencies, like Text in- and output (incl. here-strings, pipes, recorders and file-redirections on a per-function scope),- process spawning, time and random number retrieval. Later also: Filesystem access, database access, authentication and privilege escalation (passing-through IO actions).+description: Some monad transformers and typeclasses abstracting global dependencies, like Text in- and output (incl. here-strings, pipes, recorders and file-redirections on a per-function scope).+ + Note that a lot of modules have been removed since version 0.7, as they were encouraging antipatterns and had nothing to do with the core idea of chatty. Also, there will be more removals in the future! Version 1.0 will only contain core features. -- The license under which the package is released. license: AGPL-3@@ -26,13 +27,11 @@ license-file: LICENSE -- The package author(s).-author: Marvin Cohrs+author: Enum Cohrs -- An email address to which users can send suggestions, bug reports, and -- patches.-maintainer: marvin.cohrs@gmx.net--homepage: http://doomanddarkness.eu/pub/chatty+maintainer: darcs@enumeration.eu -- A copyright notice. -- copyright: @@ -48,10 +47,28 @@ -- Constraint on the version of Cabal needed to build this package. cabal-version: >=1.10 +extra-source-files: CHANGELOG.md +source-repository head+ type: darcs+ location: https://hub.darcs.net/enum/chatty + library -- Modules exported by the library.- exposed-modules: Text.Chatty.Expansion, System.Chatty.Commands, System.Chatty.Spawn, Text.Chatty.Printer, Text.Chatty.Finalizer, Text.Chatty.Templates, Text.Chatty.Scanner, Text.Chatty.Interactor, System.Chatty.Spawn.Overlay, System.Chatty.Spawn.Builtins, Text.Chatty.Interactor.Templates, System.Chatty.Misc, Text.Chatty.Extended.Printer, Text.Chatty.Extended.HTML, Text.Chatty.Extended.ANSI, Text.Chatty.Expansion.Vars, Text.Chatty.Expansion.History, Text.Chatty.Channel.Printer, Text.Chatty.Channel.Broadcast, Text.Chatty.Scanner.Buffered, System.Chatty.Filesystem+ exposed-modules: Text.Chatty.Expansion+ Text.Chatty.Printer+ Text.Chatty.Templates+ Text.Chatty.Scanner+ Text.Chatty.Interactor+ Text.Chatty.Interactor.Templates+ Text.Chatty.Extended.Printer+ Text.Chatty.Extended.HTML+ Text.Chatty.Extended.ANSI+ Text.Chatty.Expansion.Vars+ Text.Chatty.Expansion.History+ Text.Chatty.Channel.Printer+ Text.Chatty.Channel.Broadcast+ Text.Chatty.Scanner.Buffered -- Modules included in this library but not exported. -- other-modules: @@ -60,7 +77,14 @@ other-extensions: ExistentialQuantification, RankNTypes, Rank2Types, FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies, TemplateHaskell, QuasiQuotes, UndecidableInstances -- Other library packages from which modules are imported.- build-depends: base >=4.7 && <4.9, transformers >=0.3 && <0.5, directory >=1.2 && <1.3, process >=1.1 && <1.3, mtl >=2.1 && <2.3, template-haskell >=2.8 && <2.11, setenv >= 0.1 && <0.2, unix >= 2.6 && < 2.8, random >= 1.0 && < 1.1, time >= 1.4 && < 1.6, ansi-terminal >= 0.6 && <0.8, chatty-utils >= 0.7.1 && <0.8, text >=1.1 && <1.4+ build-depends: base >=4.13 && <5.0,+ transformers,+ mtl,+ template-haskell,+ ansi-terminal >= 0.6,+ chatty-utils >= 0.7.1,+ resourcet,+ text -- Directories containing source files. -- hs-source-dirs: