diff options
author | Ben Gamari <ben@smart-cactus.org> | 2017-12-08 12:42:35 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2017-12-08 13:22:41 -0500 |
commit | 7733e44dd4ba7e7a0a9f3456e6ddc32decbcf5a3 (patch) | |
tree | 79c5e7151d760e6c7617d8450fb9ec2a10560989 /hadrian/src/Hadrian/Expression.hs | |
parent | 5695f462f604fc63cbb45a7f3073bc114f9b475f (diff) | |
download | haskell-7733e44dd4ba7e7a0a9f3456e6ddc32decbcf5a3.tar.gz |
Rip out hadrian subtree
Sadly subtrees haven't worked quite as well as we would have liked for
developers. See Hadrian #440.
Diffstat (limited to 'hadrian/src/Hadrian/Expression.hs')
-rw-r--r-- | hadrian/src/Hadrian/Expression.hs | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/hadrian/src/Hadrian/Expression.hs b/hadrian/src/Hadrian/Expression.hs deleted file mode 100644 index e5c01f8935..0000000000 --- a/hadrian/src/Hadrian/Expression.hs +++ /dev/null @@ -1,153 +0,0 @@ -{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-} -module Hadrian.Expression ( - -- * Expressions - Expr, Predicate, Args, - - -- ** Construction and modification - expr, exprIO, arg, remove, - - -- ** Predicates - (?), input, inputs, output, outputs, VerboseCommand (..), verboseCommand, - - -- ** Evaluation - interpret, interpretInContext, - - -- * Convenient accessors - getBuildRoot, getContext, getBuilder, getOutputs, getInputs, getInput, getOutput - ) where - -import Control.Monad.Extra -import Control.Monad.Trans -import Control.Monad.Trans.Reader -import Data.Semigroup -import Development.Shake -import Development.Shake.Classes - -import qualified Hadrian.Target as Target -import Hadrian.Target (Target, target) -import Hadrian.Utilities - --- | 'Expr' @c b a@ is a computation that produces a value of type 'Action' @a@ --- and can read parameters of the current build 'Target' @c b@. -newtype Expr c b a = Expr (ReaderT (Target c b) Action a) - deriving (Applicative, Functor, Monad) - -instance Semigroup a => Semigroup (Expr c b a) where - Expr x <> Expr y = Expr $ (<>) <$> x <*> y - --- TODO: The 'Semigroup a' constraint will at some point become redundant. -instance (Semigroup a, Monoid a) => Monoid (Expr c b a) where - mempty = pure mempty - mappend = (<>) - --- | Expressions that compute a Boolean value. -type Predicate c b = Expr c b Bool - --- | Expressions that compute lists of arguments to be passed to builders. -type Args c b = Expr c b [String] - --- | Lift actions independent from the current build 'Target' into the 'Expr' --- monad. -expr :: Action a -> Expr c b a -expr = Expr . lift - --- | Lift IO computations independent from the current build 'Target' into the --- 'Expr' monad. -exprIO :: IO a -> Expr c b a -exprIO = Expr . liftIO - --- | Remove given elements from a list expression. -remove :: Eq a => [a] -> Expr c b [a] -> Expr c b [a] -remove xs e = filter (`notElem` xs) <$> e - --- | Add a single argument to 'Args'. -arg :: String -> Args c b -arg = pure . pure - --- | Values that can be converted to a 'Predicate'. -class ToPredicate p c b where - toPredicate :: p -> Predicate c b - -infixr 3 ? - --- | Apply a predicate to an expression. -(?) :: (Monoid a, Semigroup a, ToPredicate p c b) => p -> Expr c b a -> Expr c b a -p ? e = do - bool <- toPredicate p - if bool then e else mempty - -instance ToPredicate Bool c b where - toPredicate = pure - -instance ToPredicate p c b => ToPredicate (Action p) c b where - toPredicate = toPredicate . expr - -instance (c ~ c', b ~ b', ToPredicate p c' b') => ToPredicate (Expr c b p) c' b' where - toPredicate p = toPredicate =<< p - --- | Interpret a given expression according to the given 'Target'. -interpret :: Target c b -> Expr c b a -> Action a -interpret target (Expr e) = runReaderT e target - --- | Interpret a given expression by looking only at the given 'Context'. -interpretInContext :: c -> Expr c b a -> Action a -interpretInContext c = interpret $ target c - (error "contextOnlyTarget: builder not set") - (error "contextOnlyTarget: inputs not set" ) - (error "contextOnlyTarget: outputs not set") - --- | Get the directory of build results. -getBuildRoot :: Expr c b FilePath -getBuildRoot = expr buildRoot - --- | Get the current build 'Context'. -getContext :: Expr c b c -getContext = Expr $ asks Target.context - --- | Get the 'Builder' for the current 'Target'. -getBuilder :: Expr c b b -getBuilder = Expr $ asks Target.builder - --- | Get the input files of the current 'Target'. -getInputs :: Expr c b [FilePath] -getInputs = Expr $ asks Target.inputs - --- | Run 'getInputs' and check that the result contains one input file only. -getInput :: (Show b, Show c) => Expr c b FilePath -getInput = Expr $ do - target <- ask - fromSingleton ("Exactly one input file expected in " ++ show target) <$> - asks Target.inputs - --- | Get the files produced by the current 'Target'. -getOutputs :: Expr c b [FilePath] -getOutputs = Expr $ asks Target.outputs - --- | Run 'getOutputs' and check that the result contains one output file only. -getOutput :: (Show b, Show c) => Expr c b FilePath -getOutput = Expr $ do - target <- ask - fromSingleton ("Exactly one output file expected in " ++ show target) <$> - asks Target.outputs - --- | Does any of the input files match a given pattern? -input :: FilePattern -> Predicate c b -input f = any (f ?==) <$> getInputs - --- | Does any of the input files match any of the given patterns? -inputs :: [FilePattern] -> Predicate c b -inputs = anyM input - --- | Does any of the output files match a given pattern? -output :: FilePattern -> Predicate c b -output f = any (f ?==) <$> getOutputs - --- | Does any of the output files match any of the given patterns? -outputs :: [FilePattern] -> Predicate c b -outputs = anyM output - -newtype VerboseCommand c b = VerboseCommand { predicate :: Predicate c b } - deriving Typeable - -verboseCommand :: (ShakeValue c, ShakeValue b) => Predicate c b -verboseCommand = predicate =<< expr (userSetting . VerboseCommand $ return False) |