2024-09-25 22:09:26 +02:00
|
|
|
{-# LANGUAGE FunctionalDependencies #-}
|
2024-09-23 22:11:54 +02:00
|
|
|
module DependencyGenerator
|
|
|
|
( DepGenM
|
2024-09-24 23:01:07 +02:00
|
|
|
, DepGenM'
|
2024-09-23 22:11:54 +02:00
|
|
|
, evalDepGenM
|
|
|
|
, inject
|
|
|
|
, runFunction
|
|
|
|
, runFunctionIO
|
|
|
|
, mapDepGenM
|
|
|
|
, mapDepGenM_
|
|
|
|
, filterDepGenM
|
2024-09-25 23:32:49 +02:00
|
|
|
, untupleFstDepGenM
|
|
|
|
, untupleSndDepGenM
|
|
|
|
, untupleDepGenM
|
2024-09-25 23:06:53 +02:00
|
|
|
, unzipFstDepGenM
|
|
|
|
, unzipSndDepGenM
|
|
|
|
, unzipDepGenM
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 23:32:49 +02:00
|
|
|
, appendStrings
|
2024-09-26 00:33:52 +02:00
|
|
|
, concatStrings
|
2024-09-26 23:02:29 +02:00
|
|
|
, appendTexts
|
|
|
|
, concatTexts
|
2024-09-24 23:01:07 +02:00
|
|
|
, joinPaths
|
2024-09-25 23:06:53 +02:00
|
|
|
, fileComponents
|
2024-09-25 23:12:32 +02:00
|
|
|
, isImageExtension
|
2024-09-24 23:01:07 +02:00
|
|
|
, applyTemplate
|
2024-09-26 23:02:29 +02:00
|
|
|
, toText
|
2024-09-23 22:11:54 +02:00
|
|
|
, listDirectory
|
|
|
|
, readTemplate
|
|
|
|
, convertImage
|
|
|
|
, saveFile
|
2024-09-26 00:02:51 +02:00
|
|
|
, copyFile
|
2024-09-26 00:06:30 +02:00
|
|
|
, copyFile'
|
2024-09-24 22:38:52 +02:00
|
|
|
, makeDir
|
2024-09-23 22:11:54 +02:00
|
|
|
, runPandoc
|
|
|
|
) where
|
|
|
|
|
|
|
|
import Types.Token (Token(..))
|
|
|
|
import Types.Values
|
|
|
|
import Types.Value (Valuable(..))
|
|
|
|
import Types.Function (Function(..))
|
|
|
|
import Types.FunctionIO (FunctionIO(..))
|
2024-09-24 21:21:49 +02:00
|
|
|
import Types.Dependency (Action(..), Dependency, makeDependency)
|
2024-09-23 22:11:54 +02:00
|
|
|
|
|
|
|
import Control.Monad.State (MonadState, State, runState, put, get)
|
|
|
|
import Control.Monad.Writer (MonadWriter, WriterT, execWriterT, tell)
|
2024-09-26 23:02:29 +02:00
|
|
|
import Data.Text (Text)
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
newtype DepGenM a = DepGenM { unDepGenM :: WriterT [Dependency] (State Int) a }
|
2024-09-23 22:11:54 +02:00
|
|
|
deriving (Functor, Applicative, Monad, MonadState Int, MonadWriter [Dependency])
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
type DepGenM' a = DepGenM (Token a)
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
evalDepGenM' :: Int -> DepGenM () -> ([Dependency], Int)
|
2024-09-23 22:11:54 +02:00
|
|
|
evalDepGenM' top m = runState (execWriterT (unDepGenM m)) top
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
evalDepGenM :: DepGenM () -> [Dependency]
|
2024-09-23 22:11:54 +02:00
|
|
|
evalDepGenM m = fst (evalDepGenM' 0 m)
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
tellDep :: Dependency -> DepGenM ()
|
2024-09-23 22:11:54 +02:00
|
|
|
tellDep dep = tell [dep]
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
genDependencyM :: (Token a -> DepGenM Dependency) -> DepGenM' a
|
2024-09-23 22:11:54 +02:00
|
|
|
genDependencyM f = do
|
|
|
|
top <- get
|
|
|
|
let top' = top + 1
|
|
|
|
target = Token top'
|
|
|
|
put top'
|
|
|
|
result <- f target
|
|
|
|
tellDep result
|
|
|
|
pure target
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
genDependency :: (Token a -> Dependency) -> DepGenM' a
|
2024-09-23 22:11:54 +02:00
|
|
|
genDependency f = genDependencyM (pure . f)
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
inject :: Valuable a => a -> DepGenM' a
|
2024-09-23 22:11:54 +02:00
|
|
|
inject x = genDependency (makeDependency NoToken (Inject (toValue x)))
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
getListElem :: Token [a] -> DepGenM' a
|
2024-09-23 22:11:54 +02:00
|
|
|
getListElem outer = genDependency (makeDependency outer GetListElem)
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
setListElem :: Token a -> Token [a] -> DepGenM ()
|
2024-09-23 22:11:54 +02:00
|
|
|
setListElem a outer = do
|
|
|
|
tellDep (makeDependency a SetListElem outer)
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
runFunction :: Function -> Token a -> DepGenM' b
|
2024-09-23 22:11:54 +02:00
|
|
|
runFunction f input = genDependency (makeDependency input (Function f))
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
runFunctionIO :: FunctionIO -> Token a -> DepGenM' b
|
2024-09-23 22:11:54 +02:00
|
|
|
runFunctionIO f input = genDependency (makeDependency input (FunctionIO f))
|
|
|
|
|
2024-09-25 19:45:10 +02:00
|
|
|
runFunctionIO' :: FunctionIO -> Token a -> DepGenM ()
|
2024-09-25 22:12:38 +02:00
|
|
|
runFunctionIO' f input = tellDep $ makeDependency input (FunctionIO f) NoToken
|
2024-09-25 19:45:10 +02:00
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
mapDepGenM :: (Token a -> DepGenM' b) -> Token [a] -> DepGenM' [b]
|
2024-09-23 22:11:54 +02:00
|
|
|
mapDepGenM f input = genDependencyM $ \target -> do
|
|
|
|
top <- get
|
|
|
|
let (res, top') = evalDepGenM' top $ do
|
|
|
|
inp <- getListElem input
|
|
|
|
outp <- f inp
|
|
|
|
setListElem outp target
|
|
|
|
put top'
|
|
|
|
pure (makeDependency input (MapComp res) target)
|
|
|
|
|
2024-09-24 23:09:35 +02:00
|
|
|
mapDepGenM_ :: (Token a -> DepGenM ()) -> Token [a] -> DepGenM ()
|
2024-09-23 22:11:54 +02:00
|
|
|
mapDepGenM_ f input = do
|
2024-09-24 23:01:07 +02:00
|
|
|
_ <- mapDepGenM (\x -> f x >> pure NoToken) input
|
2024-09-24 22:23:43 +02:00
|
|
|
pure ()
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 23:12:32 +02:00
|
|
|
filterDepGenM :: Token [Bool] -> Token [a] -> DepGenM' [a]
|
|
|
|
filterDepGenM mask input = do
|
|
|
|
genDependency (makeDependency (TupleToken (input, mask)) FilterComp)
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 23:32:49 +02:00
|
|
|
untupleFstDepGenM :: TokenableTo (a, b) t => t -> DepGenM (Token a)
|
|
|
|
untupleFstDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
|
|
|
TupleToken (a, _) -> pure a
|
|
|
|
Token _ -> genDependency (makeDependency t' UntupleFst)
|
|
|
|
|
|
|
|
untupleSndDepGenM :: TokenableTo (a, b) t => t -> DepGenM (Token b)
|
|
|
|
untupleSndDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
|
|
|
TupleToken (_, b) -> pure b
|
|
|
|
Token _ -> genDependency (makeDependency t' UntupleSnd)
|
|
|
|
|
|
|
|
untupleDepGenM :: TokenableTo (a, b) t => t -> DepGenM (Token a, Token b)
|
|
|
|
untupleDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
a <- untupleFstDepGenM t'
|
|
|
|
b <- untupleSndDepGenM t'
|
|
|
|
pure (a, b)
|
|
|
|
|
2024-09-25 23:06:53 +02:00
|
|
|
unzipFstDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [a])
|
|
|
|
unzipFstDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
|
|
|
ZipToken (a, _) -> pure a
|
|
|
|
Token _ -> genDependency (makeDependency t' UnzipFst)
|
|
|
|
|
|
|
|
unzipSndDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [b])
|
|
|
|
unzipSndDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
|
|
|
ZipToken (_, b) -> pure b
|
|
|
|
Token _ -> genDependency (makeDependency t' UnzipSnd)
|
|
|
|
|
|
|
|
unzipDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [a], Token [b])
|
|
|
|
unzipDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
a <- unzipFstDepGenM t'
|
|
|
|
b <- unzipSndDepGenM t'
|
|
|
|
pure (a, b)
|
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
class TokenableTo t s | s -> t where
|
|
|
|
toToken :: s -> DepGenM' t
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
instance TokenableTo a (Token a) where
|
|
|
|
toToken = pure
|
2024-09-24 23:01:07 +02:00
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
instance TokenableTo a (DepGenM' a) where
|
|
|
|
toToken = id
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 23:32:49 +02:00
|
|
|
appendStrings :: (TokenableTo String a, TokenableTo String b) => (a, b) -> DepGenM' String
|
|
|
|
appendStrings (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunction AppendStrings $ TupleToken (a', b')
|
|
|
|
|
2024-09-26 00:33:52 +02:00
|
|
|
concatStrings :: TokenableTo [String] a => a -> DepGenM' String
|
|
|
|
concatStrings a = runFunction ConcatStrings =<< toToken a
|
|
|
|
|
2024-09-26 23:02:29 +02:00
|
|
|
appendTexts :: (TokenableTo Text a, TokenableTo Text b) => (a, b) -> DepGenM' Text
|
|
|
|
appendTexts (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunction AppendTexts $ TupleToken (a', b')
|
|
|
|
|
|
|
|
concatTexts :: TokenableTo [Text] a => a -> DepGenM' Text
|
|
|
|
concatTexts a = runFunction ConcatTexts =<< toToken a
|
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
joinPaths :: (TokenableTo FilePath a, TokenableTo FilePath b) => (a, b) -> DepGenM' FilePath
|
|
|
|
joinPaths (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunction JoinPaths $ TupleToken (a', b')
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 23:06:53 +02:00
|
|
|
fileComponents :: TokenableTo FilePath a => a -> DepGenM' (String, String)
|
|
|
|
fileComponents a = runFunction FileComponents =<< toToken a
|
|
|
|
|
2024-09-25 23:12:32 +02:00
|
|
|
isImageExtension :: TokenableTo FilePath a => a -> DepGenM' Bool
|
|
|
|
isImageExtension a = runFunction IsImageExtension =<< toToken a
|
2024-09-24 23:01:07 +02:00
|
|
|
|
2024-09-26 23:02:29 +02:00
|
|
|
applyTemplate :: (TokenableTo Template a, TokenableTo Text b) => (a, b) -> DepGenM' Text
|
2024-09-25 22:09:26 +02:00
|
|
|
applyTemplate (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunction ApplyTemplate $ TupleToken (a', b')
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-26 23:02:29 +02:00
|
|
|
toText :: TokenableTo String a => a -> DepGenM' Text
|
|
|
|
toText a = runFunction ToText =<< toToken a
|
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
listDirectory :: TokenableTo FilePath a => a -> DepGenM' [FilePath]
|
|
|
|
listDirectory a = runFunctionIO ListDirectory =<< toToken a
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
readTemplate :: TokenableTo FilePath a => a -> DepGenM' Template
|
|
|
|
readTemplate a = runFunctionIO ReadTemplate =<< toToken a
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
convertImage :: (TokenableTo (FilePath, FilePath) a, TokenableTo ImageConversionSettings b) => (a, b) -> DepGenM ()
|
|
|
|
convertImage (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunctionIO' ConvertImage $ TupleToken (a', b')
|
2024-09-24 22:38:52 +02:00
|
|
|
|
2024-09-26 23:02:29 +02:00
|
|
|
saveFile :: (TokenableTo Text a, TokenableTo FilePath b) => (a, b) -> DepGenM ()
|
2024-09-25 22:09:26 +02:00
|
|
|
saveFile (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunctionIO' SaveFile $ TupleToken (a', b')
|
|
|
|
|
2024-09-26 00:02:51 +02:00
|
|
|
copyFile :: (TokenableTo FilePath a, TokenableTo FilePath b) => (a, b) -> DepGenM ()
|
|
|
|
copyFile (a, b) = do
|
|
|
|
a' <- toToken a
|
|
|
|
b' <- toToken b
|
|
|
|
runFunctionIO' CopyFile $ TupleToken (a', b')
|
|
|
|
|
2024-09-26 00:06:30 +02:00
|
|
|
copyFile' :: Token (FilePath, FilePath) -> DepGenM ()
|
|
|
|
copyFile' = runFunctionIO' CopyFile
|
|
|
|
|
2024-09-25 22:09:26 +02:00
|
|
|
makeDir :: TokenableTo FilePath a => a -> DepGenM ()
|
|
|
|
makeDir a = runFunctionIO' MakeDir =<< toToken a
|
|
|
|
|
2024-09-26 23:02:29 +02:00
|
|
|
runPandoc :: TokenableTo FilePath a => a -> DepGenM' Text
|
2024-09-25 22:09:26 +02:00
|
|
|
runPandoc a = runFunctionIO RunPandoc =<< toToken a
|