2024-09-28 13:57:53 +02:00
|
|
|
{-# LANGUAGE GADTs #-}
|
2024-09-25 22:09:26 +02:00
|
|
|
{-# LANGUAGE FunctionalDependencies #-}
|
2024-11-09 23:13:37 +01:00
|
|
|
|
|
|
|
-- | Combinators for generating a list of dependencies between calculations, to
|
|
|
|
-- be executed later in DependencyRunner.
|
2024-11-09 22:44:46 +01:00
|
|
|
module Byg.DependencyGenerator
|
2024-09-23 22:11:54 +02:00
|
|
|
( DepGenM
|
2024-09-24 23:01:07 +02:00
|
|
|
, DepGenM'
|
2024-10-05 17:35:47 +02:00
|
|
|
, TokenableTo(..)
|
2024-10-06 15:12:31 +02:00
|
|
|
, toTupleToken
|
|
|
|
, evalDepGenM
|
2024-09-23 22:11:54 +02:00
|
|
|
, inject
|
2024-10-14 22:48:58 +02:00
|
|
|
, onToken
|
2024-10-14 23:18:21 +02:00
|
|
|
, onTupleToken
|
2024-09-23 22:11:54 +02:00
|
|
|
, runFunctionIO
|
2024-10-06 15:12:31 +02:00
|
|
|
, runFunctionIO_
|
2024-09-23 22:11:54 +02:00
|
|
|
, mapDepGenM
|
|
|
|
, mapDepGenM_
|
2024-10-05 22:51:13 +02:00
|
|
|
, forDepGenM
|
|
|
|
, forDepGenM_
|
2024-09-23 22:11:54 +02:00
|
|
|
, filterDepGenM
|
2024-10-05 21:57:04 +02:00
|
|
|
, filterDepGenM'
|
2024-09-26 23:40:26 +02:00
|
|
|
, zipDepGenM
|
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
|
|
|
) where
|
|
|
|
|
2024-11-09 22:44:46 +01:00
|
|
|
import Byg.Types.Token (Token(..))
|
|
|
|
import Byg.Types.Functions (IsFunctionIO(..))
|
|
|
|
import Byg.Types.Dependency (Action(..), F(..), Dependency, makeDependency)
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
import Type.Reflection (Typeable, TypeRep, typeRep)
|
2024-09-23 22:11:54 +02:00
|
|
|
import Control.Monad.State (MonadState, State, runState, put, get)
|
2024-09-27 20:58:18 +02:00
|
|
|
import Control.Monad.Writer (MonadWriter, WriterT, runWriterT, tell)
|
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-27 20:58:18 +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]
|
2024-09-27 20:58:18 +02:00
|
|
|
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]
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
newToken :: (Typeable a, Show a) => DepGenM (Token a)
|
2024-09-27 20:58:18 +02:00
|
|
|
newToken = do
|
2024-09-23 22:11:54 +02:00
|
|
|
top <- get
|
|
|
|
let top' = top + 1
|
|
|
|
target = Token top'
|
|
|
|
put top'
|
2024-09-27 20:58:18 +02:00
|
|
|
pure target
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
genDependencyM :: (Typeable a, Show a) => (Token a -> DepGenM Dependency) -> DepGenM (Token a)
|
2024-09-27 20:58:18 +02:00
|
|
|
genDependencyM f = do
|
|
|
|
target <- newToken
|
2024-09-23 22:11:54 +02:00
|
|
|
result <- f target
|
|
|
|
tellDep result
|
|
|
|
pure target
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
genDependency :: (Typeable a, Show a) => (Token a -> Dependency) -> DepGenM (Token a)
|
2024-09-23 22:11:54 +02:00
|
|
|
genDependency f = genDependencyM (pure . f)
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
inject :: (Show a, Typeable a) => a -> DepGenM (Token a)
|
2024-10-14 22:15:27 +02:00
|
|
|
inject x = genDependency (makeDependency NoToken (Inject x))
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-10-14 22:48:58 +02:00
|
|
|
onToken :: (TokenableTo a t, Show a, Typeable a, Show b, Typeable b) => (a -> b) -> t -> DepGenM (Token b)
|
|
|
|
onToken f input = do
|
|
|
|
input' <- toToken input
|
2024-10-14 23:18:21 +02:00
|
|
|
genDependency (makeDependency input' (Function (F f)))
|
2024-10-14 22:48:58 +02:00
|
|
|
|
2024-10-14 23:18:21 +02:00
|
|
|
onTupleToken :: (TokenableTo a t1, Show a, Typeable a, TokenableTo b t2, Show b, Typeable b, Show r, Typeable r) => (a -> b -> r) -> t1 -> t2 -> DepGenM (Token r)
|
|
|
|
onTupleToken f input1 input2 = do
|
|
|
|
tup <- toTupleToken input1 input2
|
|
|
|
genDependency (makeDependency tup (Function (F (uncurry f))))
|
2024-09-23 22:11:54 +02:00
|
|
|
|
2024-10-06 15:12:31 +02:00
|
|
|
runFunctionIO :: IsFunctionIO f a b => f -> Token a -> DepGenM (Token b)
|
2024-09-23 22:11:54 +02:00
|
|
|
runFunctionIO f input = genDependency (makeDependency input (FunctionIO f))
|
|
|
|
|
2024-10-06 13:44:19 +02:00
|
|
|
runFunctionIO_ :: IsFunctionIO f a () => f -> Token a -> DepGenM ()
|
2024-10-06 13:06:34 +02:00
|
|
|
runFunctionIO_ f input = tellDep $ makeDependency input (FunctionIO f) NoToken
|
2024-09-25 19:45:10 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
class (Show t, Typeable t) => TokenableTo t s | s -> t where
|
2024-10-06 15:12:31 +02:00
|
|
|
toToken :: s -> DepGenM (Token t)
|
2024-10-14 20:41:42 +02:00
|
|
|
tokenTypeRep :: s -> TypeRep t
|
2024-10-05 19:56:53 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
instance (Show a, Typeable a) => TokenableTo a (Token a) where
|
2024-10-05 19:56:53 +02:00
|
|
|
toToken = pure
|
2024-10-14 20:41:42 +02:00
|
|
|
tokenTypeRep _ = typeRep
|
2024-10-05 19:56:53 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
instance (Show a, Typeable a) => TokenableTo [a] [Token a] where
|
2024-10-05 20:21:06 +02:00
|
|
|
toToken = pure . ListToken
|
2024-10-14 20:41:42 +02:00
|
|
|
tokenTypeRep _ = typeRep
|
2024-10-05 20:21:06 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
instance (Show a, Typeable a) => TokenableTo a (DepGenM (Token a)) where
|
2024-10-05 19:56:53 +02:00
|
|
|
toToken = id
|
2024-10-14 20:41:42 +02:00
|
|
|
tokenTypeRep _ = typeRep
|
2024-10-05 19:56:53 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
instance (Show a, Typeable a) => TokenableTo [a] [DepGenM (Token a)] where
|
2024-10-06 15:12:31 +02:00
|
|
|
toToken = fmap ListToken . sequence
|
2024-10-14 20:41:42 +02:00
|
|
|
tokenTypeRep _ = typeRep
|
2024-10-06 15:12:31 +02:00
|
|
|
|
|
|
|
toTupleToken :: (TokenableTo ta a, TokenableTo tb b) => a -> b -> DepGenM (Token (ta, tb))
|
2024-10-05 19:56:53 +02:00
|
|
|
toTupleToken a b = TupleToken <$> toToken a <*> toToken b
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
mapDepGenM :: (TokenableTo [a] v, Typeable a, Show a, Typeable b, Show b) => (Token a -> DepGenM (Token b)) -> v -> DepGenM (Token [b])
|
2024-09-26 23:40:26 +02:00
|
|
|
mapDepGenM f input = do
|
|
|
|
input' <- toToken input
|
|
|
|
genDependencyM $ \target -> do
|
|
|
|
top <- get
|
2024-09-27 20:58:18 +02:00
|
|
|
let (((innerInp, innerOutp), subDeps), top') = runDepGenM top $ do
|
|
|
|
inp <- newToken
|
2024-09-26 23:40:26 +02:00
|
|
|
outp <- f inp
|
2024-09-27 20:58:18 +02:00
|
|
|
pure (inp, outp)
|
2024-09-26 23:40:26 +02:00
|
|
|
put top'
|
2024-10-14 22:15:27 +02:00
|
|
|
pure (makeDependency input' (MapComp subDeps innerInp innerOutp) target)
|
2024-09-26 23:40:26 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
mapDepGenM_ :: (TokenableTo [a] v, Typeable a, Show a) => (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-14 20:41:42 +02:00
|
|
|
forDepGenM :: (TokenableTo [a] v, Typeable a, Show a, Typeable b, Show b) => v -> (Token a -> DepGenM (Token b)) -> DepGenM (Token [b])
|
2024-10-05 22:51:13 +02:00
|
|
|
forDepGenM = flip mapDepGenM
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
forDepGenM_ :: (TokenableTo [a] v, Typeable a, Show a) => v -> (Token a -> DepGenM ()) -> DepGenM ()
|
2024-10-05 22:51:13 +02:00
|
|
|
forDepGenM_ = flip mapDepGenM_
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
filterDepGenM' :: (TokenableTo [Bool] v, TokenableTo [a] u, Typeable a, Show a) => v -> u -> DepGenM (Token [a])
|
2024-10-05 21:57:04 +02:00
|
|
|
filterDepGenM' mask input = do
|
2024-10-05 20:20:16 +02:00
|
|
|
tup <- toTupleToken input mask
|
2024-10-14 22:15:27 +02:00
|
|
|
genDependency (makeDependency tup FilterComp)
|
2024-09-26 23:40:26 +02:00
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
filterDepGenM :: (TokenableTo [a] v, Typeable a, Show a) => (Token a -> DepGenM (Token Bool)) -> v -> DepGenM (Token [a])
|
2024-10-05 21:57:04 +02:00
|
|
|
filterDepGenM f input = do
|
|
|
|
mask <- mapDepGenM f input
|
|
|
|
filterDepGenM' mask input
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
zipDepGenM :: (TokenableTo [a] v, TokenableTo [b] u, Typeable a, Show a, Typeable b, Show b) => v -> u -> DepGenM (Token [(a, b)])
|
2024-09-26 23:40:26 +02:00
|
|
|
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
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
untupleFstDepGenM :: (TokenableTo (a, b) t, Typeable a, Show a, Typeable b, Show b) => t -> DepGenM (Token a)
|
2024-09-25 23:32:49 +02:00
|
|
|
untupleFstDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
2024-10-14 20:41:42 +02:00
|
|
|
TupleToken a _ ->
|
|
|
|
pure a
|
|
|
|
Token _ ->
|
2024-10-14 22:15:27 +02:00
|
|
|
genDependency (makeDependency t' UntupleFst)
|
2024-10-14 20:41:42 +02:00
|
|
|
|
|
|
|
untupleSndDepGenM :: (TokenableTo (a, b) t, Typeable a, Show a, Typeable b, Show b) => t -> DepGenM (Token b)
|
2024-09-25 23:32:49 +02:00
|
|
|
untupleSndDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
2024-10-14 20:41:42 +02:00
|
|
|
TupleToken _ b ->
|
|
|
|
pure b
|
|
|
|
Token _ ->
|
2024-10-14 22:15:27 +02:00
|
|
|
genDependency (makeDependency t' UntupleSnd)
|
2024-10-14 20:41:42 +02:00
|
|
|
|
|
|
|
untupleDepGenM :: (TokenableTo (a, b) t, Typeable a, Show a, Typeable b, Show b) => t -> DepGenM (Token a, Token b)
|
2024-09-25 23:32:49 +02:00
|
|
|
untupleDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
a <- untupleFstDepGenM t'
|
|
|
|
b <- untupleSndDepGenM t'
|
|
|
|
pure (a, b)
|
|
|
|
|
2024-10-14 20:41:42 +02:00
|
|
|
unzipFstDepGenM :: (TokenableTo [(a, b)] t, Typeable a, Show a, Typeable b, Show b) => t -> DepGenM (Token [a])
|
2024-09-25 23:06:53 +02:00
|
|
|
unzipFstDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
2024-10-14 20:41:42 +02:00
|
|
|
ZipToken a _ ->
|
|
|
|
pure a
|
|
|
|
_ ->
|
2024-10-14 22:15:27 +02:00
|
|
|
genDependency (makeDependency t' UnzipFst)
|
2024-10-14 20:41:42 +02:00
|
|
|
|
|
|
|
unzipSndDepGenM :: (TokenableTo [(a, b)] t, Typeable a, Show a, Typeable b, Show b) => t -> DepGenM (Token [b])
|
2024-09-25 23:06:53 +02:00
|
|
|
unzipSndDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
case t' of
|
2024-10-14 20:41:42 +02:00
|
|
|
ZipToken _ b ->
|
|
|
|
pure b
|
|
|
|
_ ->
|
2024-10-14 22:15:27 +02:00
|
|
|
genDependency (makeDependency t' UnzipSnd)
|
2024-10-14 20:41:42 +02:00
|
|
|
|
|
|
|
unzipDepGenM :: (TokenableTo [(a, b)] t, Typeable a, Show a, Typeable b, Show b) => t -> DepGenM (Token [a], Token [b])
|
2024-09-25 23:06:53 +02:00
|
|
|
unzipDepGenM t = do
|
|
|
|
t' <- toToken t
|
|
|
|
a <- unzipFstDepGenM t'
|
|
|
|
b <- unzipSndDepGenM t'
|
|
|
|
pure (a, b)
|