Created
July 1, 2018 20:23
-
-
Save ndmitchell/857c57cfe4cf5f5af886ed3d287d50b2 to your computer and use it in GitHub Desktop.
Suspending 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspending :: forall i k v. Ord k => Scheduler Monad i i k v | |
suspending rebuilder tasks target store = fst $ execState (build target) (store, Set.empty) | |
where | |
build :: k -> State (Store i k v, Set k) () | |
build key = case tasks key of | |
Nothing -> return () | |
Just task -> do | |
done <- gets snd | |
when (key `Set.notMember` done) $ do | |
value <- gets (getValue key . fst) | |
let newTask :: Task (MonadState i) k v | |
newTask = rebuilder key value task | |
fetch :: k -> State (Store i k v, Set k) v | |
fetch k = do build k -- build the key | |
getValue k . fst <$> get | |
lens :: (Store i k v, Set k) -> (i, i -> (Store i k v, Set k)) | |
lens (store, set) = (getInfo store, \i -> (putInfo i store, set)) | |
newValue <- restate lens newTask fetch | |
modify $ \(s, d) -> (updateValue key value newValue s, Set.insert key d) | |
newtype StateX ii i a = StateX (ReaderT (ii -> (i, i -> ii)) (State ii) a) | |
deriving (Functor, Applicative, Monad) | |
instance MonadState i (StateX ii i) where | |
state f = StateX $ ReaderT $ \lens -> state $ \s -> | |
let (i, ii) = lens s | |
(a, i2) = f i | |
in (a, ii i2) | |
redo :: State ii a -> StateX ii i a | |
redo = StateX . lift | |
restate :: forall ii i k v . (ii -> (i, i -> ii)) -> Task (MonadState i) k v -> (k -> State ii v) -> State ii v | |
restate lens task fetch = StateT $ \ii -> | |
let StateX kk = run task (redo . fetch) :: StateX ii i v | |
in return $ kk `runReaderT` lens `runState` ii |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment