conceit 0.1.0.0 → 0.1.1.0
raw patch · 6 files changed
+154/−146 lines, 6 filessetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Control.Concurrent.Conceit: instance Typeable WrappedError
+ Control.Concurrent.Conceit: _Conceit :: IO a -> Conceit e a
+ Control.Concurrent.Conceit: instance Typeable1 WrappedError
Files
- CHANGELOG +4/−0
- LICENSE +27/−27
- README.md +7/−7
- Setup.hs +2/−2
- conceit.cabal +32/−32
- src/Control/Concurrent/Conceit.hs +82/−78
CHANGELOG view
@@ -0,0 +1,4 @@+0.1.1.0+=======++ - Added _Conceit.
LICENSE view
@@ -1,27 +1,27 @@-Copyright (c) 2014, Daniel Díaz Carrete -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this - list of conditions and the following disclaimer in the documentation and/or - other materials provided with the distribution. - -* Neither the name of the {organization} nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +Copyright (c) 2014, Daniel Díaz Carrete+All rights reserved.++Redistribution and use in source and binary forms, with or without modification,+are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++* Redistributions in binary form must reproduce the above copyright notice, this+ list of conditions and the following disclaimer in the documentation and/or+ other materials provided with the distribution.++* Neither the name of the {organization} nor the names of its+ contributors may be used to endorse or promote products derived from+ this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
README.md view
@@ -1,7 +1,7 @@-conceit -======= - -A version of the async package's Concurrently for which the computations can -be interrupted by returning a Left value. - -Includes a useful Bifunctor instance. +conceit+=======++A version of the async package's Concurrently for which the computations can+be interrupted by returning a Left value.++Includes a useful Bifunctor instance.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple -main = defaultMain +import Distribution.Simple+main = defaultMain
conceit.cabal view
@@ -1,32 +1,32 @@-name: conceit -version: 0.1.0.0 -license: BSD3 -license-file: LICENSE -data-files: -author: Daniel Díaz Carrete -maintainer: diaz_carrete@yahoo.com -category: Concurrency -build-type: Simple -cabal-version: >= 1.10 -Synopsis: Concurrent actions that may fail -Description: A version of the async package's 'Control.Concurrent.Async.Concurrently' for which the actions may fail - -Extra-Source-Files: - README.md - CHANGELOG - -Library - default-language: Haskell2010 - hs-source-dirs: src - exposed-modules: - Control.Concurrent.Conceit - other-modules: - build-depends: - base >= 4.4 && < 5, - bifunctors >= 4.1 && < 5, - async >= 2.0.1 && < 2.1 - -Source-repository head - type: git - location: https://github.com/danidiaz/conceit.git - +name: conceit+version: 0.1.1.0+license: BSD3+license-file: LICENSE+data-files: +author: Daniel Díaz Carrete+maintainer: diaz_carrete@yahoo.com+category: Concurrency+build-type: Simple+cabal-version: >= 1.10+Synopsis: Concurrent actions that may fail+Description: A version of the async package's 'Control.Concurrent.Async.Concurrently' for which the actions may fail++Extra-Source-Files:+ README.md+ CHANGELOG++Library+ default-language: Haskell2010+ hs-source-dirs: src+ exposed-modules: + Control.Concurrent.Conceit+ other-modules: + build-depends: + base >= 4.4 && < 5,+ bifunctors >= 4.1 && < 5,+ async >= 2.0.1 && < 2.1++Source-repository head+ type: git+ location: https://github.com/danidiaz/conceit.git+
src/Control/Concurrent/Conceit.hs view
@@ -1,78 +1,82 @@-{-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE DeriveFunctor #-} - -module Control.Concurrent.Conceit ( - Conceit (..) - , conceit - , mapConceit - ) where - -import Data.Bifunctor -import Data.Monoid -import Data.Typeable -import Data.Traversable -import Control.Applicative -import Control.Monad -import Control.Exception -import Control.Concurrent -import Control.Concurrent.Async - -data WrappedError e = WrappedError e - deriving (Show, Typeable) - -instance (Show e, Typeable e) => Exception (WrappedError e) - -elideError :: (Show e, Typeable e) => IO (Either e a) -> IO a -elideError action = action >>= either (throwIO . WrappedError) return - -revealError :: (Show e, Typeable e) => IO a -> IO (Either e a) -revealError action = catch (action >>= return . Right) - (\(WrappedError e) -> return . Left $ e) - -{-| - 'Conceit' is very similar to 'Control.Concurrent.Async.Concurrently' from the -@async@ package, but it has an explicit error type @e@. - - The 'Applicative' instance is used to run actions concurrently, wait until -they finish, and combine their results. - - However, if any of the actions fails with @e@ the other actions are -immediately cancelled and the whole computation fails with @e@. - - To put it another way: 'Conceit' behaves like 'Concurrently' for successes and -like 'race' for errors. --} -newtype Conceit e a = Conceit { runConceit :: IO (Either e a) } deriving Functor - -instance Bifunctor Conceit where - bimap f g (Conceit x) = Conceit $ liftM (bimap f g) x - -instance (Show e, Typeable e) => Applicative (Conceit e) where - pure = Conceit . pure . pure - Conceit fs <*> Conceit as = - Conceit . revealError $ - uncurry ($) <$> concurrently (elideError fs) (elideError as) - -instance (Show e, Typeable e) => Alternative (Conceit e) where - empty = Conceit $ forever (threadDelay maxBound) - Conceit as <|> Conceit bs = - Conceit $ either id id <$> race as bs - -instance (Show e, Typeable e, Monoid a) => Monoid (Conceit e a) where - mempty = Conceit . pure . pure $ mempty - mappend c1 c2 = (<>) <$> c1 <*> c2 - -conceit :: (Show e, Typeable e) - => IO (Either e a) - -> IO (Either e b) - -> IO (Either e (a,b)) -conceit c1 c2 = runConceit $ (,) <$> Conceit c1 <*> Conceit c2 - -{-| - Works similarly to 'Control.Concurrent.Async.mapConcurrently' from the -@async@ package, but if any of the computations fails with @e@, the others are -immediately cancelled and the whole computation fails with @e@. - -} -mapConceit :: (Show e, Typeable e, Traversable t) => (a -> IO (Either e b)) -> t a -> IO (Either e (t b)) -mapConceit f = revealError . mapConcurrently (elideError . f) - +{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE DeriveFunctor #-}++module Control.Concurrent.Conceit ( + Conceit (..)+ , _Conceit+ , conceit+ , mapConceit+ ) where++import Data.Bifunctor+import Data.Monoid+import Data.Typeable+import Data.Traversable+import Control.Applicative+import Control.Monad+import Control.Exception+import Control.Concurrent+import Control.Concurrent.Async++data WrappedError e = WrappedError e+ deriving (Show, Typeable)++instance (Show e, Typeable e) => Exception (WrappedError e)++elideError :: (Show e, Typeable e) => IO (Either e a) -> IO a+elideError action = action >>= either (throwIO . WrappedError) return++revealError :: (Show e, Typeable e) => IO a -> IO (Either e a) +revealError action = catch (action >>= return . Right)+ (\(WrappedError e) -> return . Left $ e) ++{-| + 'Conceit' is very similar to 'Control.Concurrent.Async.Concurrently' from the+@async@ package, but it has an explicit error type @e@.++ The 'Applicative' instance is used to run actions concurrently, wait until+they finish, and combine their results. ++ However, if any of the actions fails with @e@ the other actions are+immediately cancelled and the whole computation fails with @e@. ++ To put it another way: 'Conceit' behaves like 'Concurrently' for successes and+like 'race' for errors. +-}+newtype Conceit e a = Conceit { runConceit :: IO (Either e a) } deriving Functor++instance Bifunctor Conceit where+ bimap f g (Conceit x) = Conceit $ liftM (bimap f g) x++instance (Show e, Typeable e) => Applicative (Conceit e) where+ pure = Conceit . pure . pure+ Conceit fs <*> Conceit as =+ Conceit . revealError $ + uncurry ($) <$> concurrently (elideError fs) (elideError as)++instance (Show e, Typeable e) => Alternative (Conceit e) where+ empty = Conceit $ forever (threadDelay maxBound)+ Conceit as <|> Conceit bs =+ Conceit $ either id id <$> race as bs++instance (Show e, Typeable e, Monoid a) => Monoid (Conceit e a) where+ mempty = Conceit . pure . pure $ mempty+ mappend c1 c2 = (<>) <$> c1 <*> c2++_Conceit :: IO a -> Conceit e a+_Conceit = Conceit . fmap pure ++conceit :: (Show e, Typeable e) + => IO (Either e a)+ -> IO (Either e b)+ -> IO (Either e (a,b))+conceit c1 c2 = runConceit $ (,) <$> Conceit c1 <*> Conceit c2++{-| + Works similarly to 'Control.Concurrent.Async.mapConcurrently' from the+@async@ package, but if any of the computations fails with @e@, the others are+immediately cancelled and the whole computation fails with @e@. + -}+mapConceit :: (Show e, Typeable e, Traversable t) => (a -> IO (Either e b)) -> t a -> IO (Either e (t b))+mapConceit f = revealError . mapConcurrently (elideError . f)+