future-resource 0.3.0.0 → 0.4.0.0
raw patch · 2 files changed
+75/−75 lines, 2 filesdep +transformersdep ~basePVP ok
version bump matches the API change (PVP)
Dependencies added: transformers
Dependency ranges changed: base
API changes (from Hackage documentation)
- Control.Future: asyncIO :: ((Progress [a] b -> IO ()) -> IO ()) -> IO (Future a b)
- Control.Future: eitherChance :: Future a b -> IO (Progress [a] b)
- Control.Future: forceFuture :: Future a b -> ([a] -> IO b) -> IO b
- Control.Future: instance Alternative (Future a)
- Control.Future: instance Applicative (Future a)
- Control.Future: instance Monad (Future a)
- Control.Future: runAction :: Future a (IO b) -> IO ()
- Control.Future: waitFuture :: Future a b -> IO (Progress [a] b)
+ Control.Future: desire :: MonadIO m => Future a b -> (a -> IO b) -> m b
+ Control.Future: expect :: Show a => Future a b -> IO b
+ Control.Future: getProgress :: MonadIO m => Future a b -> m (Progress a b)
+ Control.Future: instance Monoid a => Alternative (Future a)
+ Control.Future: instance Monoid a => Applicative (Future a)
+ Control.Future: instance Monoid a => Monad (Future a)
+ Control.Future: mkFuture :: MonadIO m => ((Progress a b -> IO ()) -> IO ()) -> m (Future a b)
+ Control.Future: waitFor :: MonadIO m => Future a b -> m (Progress a b)
- Control.Future: Future :: IO (Progress [a] b) -> Future a b
+ Control.Future: Future :: IO (Progress a b) -> Future a b
- Control.Future: maybeChance :: Future a b -> ([a] -> IO b) -> IO (Maybe b)
+ Control.Future: maybeChance :: MonadIO m => Future a b -> (a -> IO b) -> m (Maybe b)
- Control.Future: runFuture :: Future a b -> IO (Progress [a] b)
+ Control.Future: runFuture :: Future a b -> IO (Progress a b)
- Control.Future: type Future' = Future String
+ Control.Future: type Future' = Future [String]
Files
- Control/Future.hs +69/−69
- future-resource.cabal +6/−6
Control/Future.hs view
@@ -4,93 +4,93 @@ module Control.Future where import Control.Applicative import Control.Concurrent+import Control.Monad.IO.Class import Data.IORef+import Data.Monoid data Progress a b = Making | Fixme a | Finished b- deriving (Functor, Show)+ deriving (Functor, Show) -- | Two kinds of future is possible:--- (i) A pile of failures [a] and (ii) Successful result b.-newtype Future a b = Future { runFuture :: IO (Progress [a] b) }+-- (i) A pile of failures (Monoid a) and (ii) Successful result b.+newtype Future a b = Future { runFuture :: IO (Progress a b) } instance Functor (Future a) where- fmap f (Future a) = Future $ (fmap.fmap) f a+ fmap f (Future a) = Future $ (fmap.fmap) f a -instance Applicative (Future a) where- pure = Future . return . Finished- Future fs <*> Future as =- Future $ do- fs' <- fs- as' <- as- return $ case (fs', as') of- (Finished f, Finished a) -> Finished $ f a- (Fixme f, Finished _) -> Fixme f- (Finished _, Fixme a) -> Fixme a- (Fixme f, Fixme a) -> Fixme (f ++ a)- _ -> Making+instance Monoid a => Applicative (Future a) where+ pure = Future . return . Finished+ Future fs <*> Future as =+ Future $ do+ fs' <- fs+ as' <- as+ return $ case (fs', as') of+ (Finished f, Finished a) -> Finished $ f a+ (Fixme f, Finished _) -> Fixme f+ (Finished _, Fixme a) -> Fixme a+ (Fixme f, Fixme a) -> Fixme (f `mappend` a)+ _ -> Making -instance Alternative (Future a) where- empty = Future $ return Making- Future as <|> Future bs =- Future $ do- as' <- as- case as' of- Finished _ -> return as'- _ -> bs+instance Monoid a => Alternative (Future a) where+ empty = Future $ return Making+ Future as <|> Future bs =+ Future $ do+ as' <- as+ case as' of+ Finished _ -> return as'+ _ -> bs -instance Monad (Future a) where- return = pure- Future m >>= f =- Future $ do- m' <- m- case m' of- Finished x -> runFuture (f x)- Fixme l -> return (Fixme l)- Making -> return Making+instance Monoid a => Monad (Future a) where+ return = pure+ Future m >>= f =+ Future $ do+ m' <- m+ case m' of+ Finished x -> runFuture (f x)+ Fixme l -> return (Fixme l)+ Making -> return Making -type Future' = Future String+type Future' = Future [String] -- | Wait until future comes, and modify failure history.-forceFuture :: Future a b -> ([a] -> IO b) -> IO b-forceFuture fu@(Future fs) f = do- fs' <- fs- case fs' of- Finished r -> return r- Fixme l -> f l- Making -> threadDelay 1000 >> forceFuture fu f+desire :: MonadIO m => Future a b -> (a -> IO b) -> m b+desire future@(Future f) fix = liftIO $ do+ prog <- f+ case prog of+ Finished result -> return result+ Fixme err -> fix err+ Making -> threadDelay 1000 >> desire future fix -- | Just wait for the future honestly.-waitFuture :: Future a b -> IO (Progress [a] b)-waitFuture fu@(Future fs) = do- fs' <- fs- case fs' of- Making -> threadDelay 1000 >> waitFuture fu- otherwise -> return fs'+waitFor :: MonadIO m => Future a b -> m (Progress a b)+waitFor future@(Future f) = liftIO $ do+ prog <- f+ case prog of+ Making -> threadDelay 1000 >> waitFor future+ otherwise -> return prog -- | Return 'Just' when it is time. The history may be modified.-maybeChance :: Future a b -> ([a] -> IO b) -> IO (Maybe b)-maybeChance (Future fs) f = do- fs' <- fs- case fs' of- Finished r -> return $ Just r- Fixme l -> f l >>= return . Just- Making -> return Nothing+maybeChance :: MonadIO m => Future a b -> (a -> IO b) -> m (Maybe b)+maybeChance (Future f) fix = liftIO $ do+ prog <- f+ case prog of+ Finished result -> return $ Just result+ Fixme err -> fix err >>= return . Just+ Making -> return Nothing -- | If it is too early, immediately returns 'Making'.-eitherChance :: Future a b -> IO (Progress [a] b)-eitherChance (Future fs) = fs+getProgress :: MonadIO m => Future a b -> m (Progress a b)+getProgress (Future f) = liftIO f --- | > asyncIO $ \update -> forkIO (doSth >>= update)-asyncIO :: ((Progress [a] b -> IO ()) -> IO ()) -> IO (Future a b)-asyncIO makeThread = do- ref <- newIORef Making- makeThread (writeIORef ref)- return $ Future $ readIORef ref+-- | > mkFuture $ \updateProgress -> forkIO (doSth >>= updateProgress)+mkFuture :: MonadIO m => ((Progress a b -> IO ()) -> IO ()) -> m (Future a b)+mkFuture doFork = liftIO $ do+ progRef <- newIORef Making+ doFork (writeIORef progRef)+ return $ Future $ readIORef progRef --- | Run an action created in given 'Future' if it is available now.-runAction :: Future a (IO b) -> IO ()-runAction (Future fs) = do- fs' <- fs- case fs' of- Finished run -> run >> return ()- otherwise -> return ()+-- | Run 'Future' action immediately.+expect :: Show a => Future a b -> IO b+expect future =+ desire future (\a -> error $ "Control.Future.expect: " ++ show a)+
future-resource.cabal view
@@ -1,12 +1,12 @@ name: future-resource-version: 0.3.0.0+version: 0.4.0.0 synopsis: realtime resource handling with manual concurrency-description: Similar to async package, lazy resource loading framework for GUI applications+description: Similar to async package, lazy resource loading helper for GUI applications license: LGPL-3 license-file: LICENSE-author: capsjac-maintainer: capsjac--- copyright: +author: capsjac <capsjac at gmail dot com>+maintainer: capsjac <capsjac at gmail dot com>+copyright: (c) 2014 capsjac category: Control build-type: Simple -- extra-source-files: @@ -20,6 +20,6 @@ exposed-modules: Control.Future -- other-modules: -- other-extensions: - build-depends: base >=4.7 && <4.8+ build-depends: base >=4.7 && <5, transformers -- hs-source-dirs: default-language: Haskell2010