mad/byg/src/DependencyGenerator.hs

285 lines
8.8 KiB
Haskell
Raw Normal View History

2024-09-28 13:57:53 +02:00
{-# LANGUAGE GADTs #-}
{-# 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
, TokenableTo(..)
2024-09-23 22:11:54 +02:00
, inject
, runFunction
, runFunctionIO
, mapDepGenM
, mapDepGenM_
2024-10-05 22:51:13 +02:00
, forDepGenM
, forDepGenM_
2024-09-23 22:11:54 +02:00
, filterDepGenM
, filterDepGenM'
2024-09-26 23:40:26 +02:00
, zipDepGenM
, untupleFstDepGenM
, untupleSndDepGenM
, untupleDepGenM
2024-09-25 23:06:53 +02:00
, unzipFstDepGenM
, unzipSndDepGenM
, unzipDepGenM
2024-09-23 22:11:54 +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
, lowerString
, elemOf
, makeTemplate
2024-09-24 23:01:07 +02:00
, applyTemplate
2024-09-26 23:02:29 +02:00
, toText
2024-10-05 23:37:54 +02:00
, convertImage
2024-09-23 22:11:54 +02:00
, listDirectory
2024-09-30 23:30:43 +02:00
, isDirectory
, readTextFile
2024-10-05 23:37:54 +02:00
, openImage
, saveImage
2024-10-05 22:51:13 +02:00
, saveTextFile
2024-09-26 00:02:51 +02:00
, copyFile
, copyFile'
2024-09-24 22:38:52 +02:00
, makeDir
2024-09-23 22:11:54 +02:00
, runPandoc
2024-10-05 22:51:13 +02:00
, hasExtension
, copyTo
2024-09-23 22:11:54 +02:00
) where
import Prelude hiding (String, FilePath)
2024-09-23 22:11:54 +02:00
import Types.Token (Token(..))
import Types.Values
import Types.Value (Valuable(..))
import Types.Function (Function(..))
2024-10-06 13:06:34 +02:00
import Types.FunctionIO
import Types.Dependency (Action(..), Dependency, makeDependency, makeUToken)
2024-09-23 22:11:54 +02:00
import Control.Monad.State (MonadState, State, runState, put, get)
import Control.Monad.Writer (MonadWriter, WriterT, runWriterT, 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
runDepGenM :: Int -> DepGenM a -> ((a, [Dependency]), Int)
runDepGenM top m = runState (runWriterT (unDepGenM m)) top
2024-09-23 22:11:54 +02:00
2024-09-24 23:09:35 +02:00
evalDepGenM :: DepGenM () -> [Dependency]
evalDepGenM = snd . fst . runDepGenM 0
2024-09-23 22:11:54 +02:00
2024-09-24 23:09:35 +02:00
tellDep :: Dependency -> DepGenM ()
2024-09-23 22:11:54 +02:00
tellDep dep = tell [dep]
newToken :: DepGenM' a
newToken = do
2024-09-23 22:11:54 +02:00
top <- get
let top' = top + 1
target = Token top'
put top'
pure target
genDependencyM :: (Token a -> DepGenM Dependency) -> DepGenM' a
genDependencyM f = do
target <- newToken
2024-09-23 22:11:54 +02:00
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
runFunction :: Function -> Token a -> DepGenM' b
2024-09-23 22:11:54 +02:00
runFunction f input = genDependency (makeDependency input (Function f))
2024-10-06 13:06:34 +02:00
runFunctionIO :: IsFunctionIO f => f -> Token a -> DepGenM' b
2024-09-23 22:11:54 +02:00
runFunctionIO f input = genDependency (makeDependency input (FunctionIO f))
2024-10-06 13:06:34 +02:00
runFunctionIO_ :: IsFunctionIO f => f -> Token a -> DepGenM ()
runFunctionIO_ f input = tellDep $ makeDependency input (FunctionIO f) NoToken
2024-09-25 19:45:10 +02:00
2024-10-05 19:56:53 +02:00
class TokenableTo t s | s -> t where
toToken :: s -> DepGenM' t
instance TokenableTo a (Token a) where
toToken = pure
instance TokenableTo [a] [Token a] where
toToken = pure . ListToken
2024-10-05 20:28:25 +02:00
instance TokenableTo [a] [DepGenM' a] where
toToken = fmap ListToken . sequence
2024-10-05 19:56:53 +02:00
instance TokenableTo a (DepGenM' a) where
toToken = id
toTupleToken :: (TokenableTo ta a, TokenableTo tb b) => a -> b -> DepGenM' (ta, tb)
toTupleToken a b = TupleToken <$> toToken a <*> toToken b
2024-09-26 23:40:26 +02:00
mapDepGenM :: TokenableTo [a] v => (Token a -> DepGenM' b) -> v -> DepGenM' [b]
mapDepGenM f input = do
input' <- toToken input
genDependencyM $ \target -> do
top <- get
let (((innerInp, innerOutp), subDeps), top') = runDepGenM top $ do
inp <- newToken
2024-09-26 23:40:26 +02:00
outp <- f inp
pure (inp, outp)
2024-09-26 23:40:26 +02:00
put top'
pure (makeDependency input' (MapComp subDeps (makeUToken innerInp) (makeUToken innerOutp)) target)
2024-09-26 23:40:26 +02:00
mapDepGenM_ :: TokenableTo [a] v => (Token a -> DepGenM ()) -> v -> 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-10-05 22:51:13 +02:00
forDepGenM :: TokenableTo [a] v => v -> (Token a -> DepGenM' b) -> DepGenM' [b]
forDepGenM = flip mapDepGenM
forDepGenM_ :: TokenableTo [a] v => v -> (Token a -> DepGenM ()) -> DepGenM ()
forDepGenM_ = flip mapDepGenM_
filterDepGenM' :: (TokenableTo [Bool] v, TokenableTo [a] u) => v -> u -> DepGenM' [a]
filterDepGenM' mask input = do
2024-10-05 20:20:16 +02:00
tup <- toTupleToken input mask
2024-10-05 19:56:53 +02:00
genDependency (makeDependency tup FilterComp)
2024-09-26 23:40:26 +02:00
filterDepGenM :: TokenableTo [a] v => (Token a -> DepGenM' Bool) -> v -> DepGenM' [a]
filterDepGenM f input = do
mask <- mapDepGenM f input
filterDepGenM' mask input
2024-09-26 23:40:26 +02:00
zipDepGenM :: (TokenableTo [a] v, TokenableTo [b] u) => v -> u -> DepGenM' [(a, b)]
zipDepGenM a b = do
a' <- toToken a
b' <- toToken b
2024-10-05 19:44:28 +02:00
pure $ ZipToken a' b'
2024-09-23 22:11:54 +02:00
untupleFstDepGenM :: TokenableTo (a, b) t => t -> DepGenM (Token a)
untupleFstDepGenM t = do
t' <- toToken t
case t' of
2024-10-05 19:44:28 +02:00
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
2024-10-05 19:44:28 +02:00
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
2024-10-05 19:44:28 +02:00
ZipToken a _ -> pure a
_ -> genDependency (makeDependency t' UnzipFst)
2024-09-25 23:06:53 +02:00
unzipSndDepGenM :: TokenableTo [(a, b)] t => t -> DepGenM (Token [b])
unzipSndDepGenM t = do
t' <- toToken t
case t' of
2024-10-05 19:44:28 +02:00
ZipToken _ b -> pure b
_ -> genDependency (makeDependency t' UnzipSnd)
2024-09-25 23:06:53 +02:00
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-26 23:40:26 +02:00
appendStrings :: (TokenableTo String a, TokenableTo String b) => a -> b -> DepGenM' String
2024-10-05 19:56:53 +02:00
appendStrings a b = runFunction AppendStrings =<< TupleToken <$> toToken a <*> toToken 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:40:26 +02:00
appendTexts :: (TokenableTo Text a, TokenableTo Text b) => a -> b -> DepGenM' Text
2024-10-05 19:56:53 +02:00
appendTexts a b = runFunction AppendTexts =<< toTupleToken a b
2024-09-26 23:02:29 +02:00
concatTexts :: TokenableTo [Text] a => a -> DepGenM' Text
concatTexts a = runFunction ConcatTexts =<< toToken a
2024-09-26 23:40:26 +02:00
joinPaths :: (TokenableTo FilePath a, TokenableTo FilePath b) => a -> b -> DepGenM' FilePath
2024-10-05 19:56:53 +02:00
joinPaths a b = runFunction JoinPaths =<< TupleToken <$> toToken a <*> toToken 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
lowerString :: TokenableTo String a => a -> DepGenM' String
lowerString a = runFunction LowerString =<< toToken a
elemOf :: (TokenableTo String a, TokenableTo [String] b) => a -> b -> DepGenM' Bool
2024-10-05 19:56:53 +02:00
elemOf a b = runFunction ElemOf =<< toTupleToken a b
2024-09-24 23:01:07 +02:00
makeTemplate :: (TokenableTo Text a, TokenableTo Text b) => a -> b -> DepGenM' Template
2024-10-05 19:56:53 +02:00
makeTemplate a b = runFunction MakeTemplate =<< toTupleToken a b
2024-09-26 23:40:26 +02:00
applyTemplate :: (TokenableTo Template a, TokenableTo Text b) => a -> b -> DepGenM' Text
2024-10-05 19:56:53 +02:00
applyTemplate a b = runFunction ApplyTemplate =<< toTupleToken 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-10-05 23:37:54 +02:00
convertImage :: (TokenableTo Image a, TokenableTo ImageConversionSettings b) => a -> b -> DepGenM' Image
convertImage a b = runFunction ConvertImage =<< toTupleToken a b
2024-10-06 00:03:11 +02:00
runPandoc :: TokenableTo Text a => a -> DepGenM' Text
runPandoc a = runFunction RunPandoc =<< toToken a
listDirectory :: TokenableTo FilePath a => a -> DepGenM' [FilePath]
listDirectory a = runFunctionIO ListDirectory =<< toToken a
2024-09-23 22:11:54 +02:00
2024-09-30 23:30:43 +02:00
isDirectory :: TokenableTo FilePath a => a -> DepGenM' Bool
isDirectory a = runFunctionIO IsDirectory =<< toToken a
readTextFile :: TokenableTo FilePath a => a -> DepGenM' Text
readTextFile a = runFunctionIO ReadTextFile =<< toToken a
2024-09-23 22:11:54 +02:00
2024-10-05 23:37:54 +02:00
openImage :: TokenableTo FilePath a => a -> DepGenM' Image
openImage a = runFunctionIO OpenImage =<< toToken a
saveImage :: (TokenableTo Image a, TokenableTo FilePath b) => a -> b -> DepGenM ()
2024-10-06 13:06:34 +02:00
saveImage a b = runFunctionIO_ SaveImage =<< toTupleToken a b
2024-09-24 22:38:52 +02:00
2024-10-05 22:51:13 +02:00
saveTextFile :: (TokenableTo Text a, TokenableTo FilePath b) => a -> b -> DepGenM ()
2024-10-06 13:06:34 +02:00
saveTextFile a b = runFunctionIO_ SaveTextFile =<< toTupleToken a b
2024-09-26 23:40:26 +02:00
copyFile :: (TokenableTo FilePath a, TokenableTo FilePath b) => a -> b -> DepGenM ()
2024-10-06 13:06:34 +02:00
copyFile a b = runFunctionIO_ CopyFile =<< toTupleToken a b
2024-09-26 00:02:51 +02:00
copyFile' :: Token (FilePath, FilePath) -> DepGenM ()
2024-10-06 13:06:34 +02:00
copyFile' = runFunctionIO_ CopyFile
makeDir :: TokenableTo FilePath a => a -> DepGenM ()
2024-10-06 13:06:34 +02:00
makeDir a = runFunctionIO_ MakeDir =<< toToken a
2024-10-05 22:51:13 +02:00
hasExtension :: (TokenableTo [String] a, TokenableTo FilePath b) => a -> b -> DepGenM' Bool
hasExtension exts filename = do
ext <- lowerString $ untupleSndDepGenM $ fileComponents filename
ext `elemOf` exts
copyTo :: (TokenableTo FilePath a, TokenableTo FilePath b) => a -> b -> DepGenM ()
2024-10-05 23:42:40 +02:00
copyTo path targetDir = do
pathToken <- toToken path
copyFile pathToken (joinPaths targetDir pathToken)