{-# LANGUAGE ScopedTypeVariables #-}
module Build.Task.Monad (
track, trackPure, isInput, computePure, compute, partial, exceptional
) where
import Control.Monad.Trans
import Control.Monad.Trans.Except
import Control.Monad.Trans.Maybe
import Control.Monad.Writer
import Data.Functor.Identity
import Data.Maybe
import Build.Store
import Build.Task
trackPure :: Task Monad k v -> (k -> v) -> (v, [k])
trackPure task fetch = runWriter $ run task (\k -> writer (fetch k, [k]))
track :: forall m k v. Monad m => Task Monad k v -> (k -> m v) -> m (v, [(k, v)])
track task fetch = runWriterT $ run task trackingFetch
where
trackingFetch :: k -> WriterT [(k, v)] m v
trackingFetch k = do
v <- lift $ fetch k
tell [(k, v)]
return v
isInput :: Tasks Monad k v -> k -> Bool
isInput tasks = isNothing . tasks
computePure :: Task Monad k v -> (k -> v) -> v
computePure task store = runIdentity $ run task (Identity . store)
compute :: Task Monad k v -> Store i k v -> v
compute task store = runIdentity $ run task (\k -> Identity (getValue k store))
partial :: Task Monad k v -> Task Monad k (Maybe v)
partial task = Task $ \fetch -> runMaybeT $ run task (MaybeT . fetch)
exceptional :: Task Monad k v -> Task Monad k (Either e v)
exceptional task = Task $ \fetch -> runExceptT $ run task (ExceptT . fetch)