packages feed

unamb 0.0.1 → 0.1.0

raw patch · 3 files changed

+66/−32 lines, 3 filesdep ~basePVP ok

version bump matches the API change (PVP)

Dependency ranges changed: base

API changes (from Hackage documentation)

+ Data.Unamb: bottom :: a

Files

src/Data/Unamb.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE ScopedTypeVariables, RecursiveDo, CPP #-} {-# OPTIONS_GHC -Wall #-} ---------------------------------------------------------------------- -- |@@ -12,18 +12,24 @@ -- Unambiguous choice ---------------------------------------------------------------------- +#include "Typeable.h"+ module Data.Unamb   (-    unamb, amb, race, assuming, hang, asAgree+    bottom, unamb, assuming, asAgree, hang+  , amb, race   ) where +import Prelude hiding (catch) -- For hang-import Control.Monad (forever)+-- import Control.Monad (forever) import System.IO.Unsafe --- For unamb+-- import Data.Dynamic+ import Control.Concurrent-import Control.Exception (evaluate)+import Control.Exception+  (evaluate, BlockedOnDeadMVar(..), catch, throw)   -- | Unambiguous choice operator.  Equivalent to the ambiguous choice@@ -43,35 +49,50 @@ -- whichever finishes first.  See also 'amb'.  Thanks to Spencer Janssen -- for this simple version. race :: IO a -> IO a -> IO a+ a `race` b = do v  <- newEmptyMVar-                ta <- forkIO (a >>= putMVar v)-                tb <- forkIO (b >>= putMVar v)+                ta <- forkIO' (a >>= putMVar v)+                tb <- forkIO' (b >>= putMVar v)                 x  <- takeMVar v                 killThread ta                 killThread tb                 return x --- Without using unsafePerformIO, is there a way to define a--- non-terminating but non-erroring pure value that consume very little--- resources while not terminating?+-- Use a particular exception as our representation for waiting forever.+-- A thread can bottom-out efficiently by throwing that exception.  If both+-- threads bail out, then the 'takeMVar' would block.  In that case, the+-- run-time system would notice and raise 'BlockedOnDeadMVar'.  I'd then+-- want to convert that exception into the one that wait-forever+-- exception.  As an expedient hack, I use 'BlockedOnDeadMVar' as the+-- wait-forever exception, so that no conversion is needed.  Perhaps+-- revisit this choice, and define our own exception class, for clarity+-- and easier debugging. ++-- Fork a thread to execute a given action.  Silence any raised exceptions.+forkIO' :: IO () -> IO ThreadId+forkIO' act = forkIO (act `catch` handler)+ where+   handler :: BlockedOnDeadMVar -> IO ()+   handler = const (return ())++-- I'd like @hang `unamb` hang@ to quickly terminate, throwing an+-- exception.  I'm surprised that it doesn't lead to 'BlockedOnDeadMVar'.+-- Why doesn't it??  Oh -- maybe it does, when compiled.+++-- | A 'bottom' value, allowing no information out.  A left- and right-+-- identity for 'unamb'.  At the top level, evaluating 'bottom' results in+-- the message "Exception: thread blocked indefinitely".+bottom :: a+bottom = throw BlockedOnDeadMVar++-- {-# DEPRECATED hang "use bottom instead" #-}+ -- | Never yield an answer.  Like 'undefined' or 'error "whatever"', but -- don't raise an error, and don't consume computational resources. hang :: a-hang = unsafePerformIO hangIO---- | Block forever.-hangIO :: IO a-hangIO = do -- putStrLn "warning: blocking forever."-            -- Any never-terminating computation goes here-            -- This one can yield an exception "thread blocked indefinitely"-            -- newEmptyMVar >>= takeMVar-            -- sjanssen suggests this alternative:-            forever $ threadDelay maxBound-            -- forever's return type is (), though it could be fully-            -- polymorphic.  Until it's fixed, I need the following line.-            return undefined-+hang = bottom  -- | Yield a value if a condition is true.  Otherwise wait forever. assuming :: Bool -> a -> a@@ -80,3 +101,19 @@ -- | The value of agreeing values (or hang) asAgree :: Eq a => a -> a -> a a `asAgree` b = assuming (a == b) a++----++{-++data WaitForever = WaitForever++INSTANCE_TYPEABLE0(WaitForever,waitForeverTc,"WaitForever")++instance Show WaitForever where+    showsPrec _ WaitForever = showString "waiting for, like, evar"+instance Exception WaitForever++-}++----
unamb.cabal view
@@ -1,5 +1,5 @@ Name:                unamb-Version:             0.0.1+Version:             0.1.0 Cabal-Version:       >= 1.2 Synopsis:            Unambiguous choice Category:            Concurrency, Data, Other@@ -10,9 +10,6 @@   package in order to encourage experimentation.   .   Project wiki page: <http://haskell.org/haskellwiki/unamb>-  .-  The module documentation pages have links to colorized source code and-  to wiki pages where you can read and contribute user comments.  Enjoy!   .   &#169; 2008 by Conal Elliott; BSD3 license.   .
wikipage.tw view
@@ -7,9 +7,9 @@ <hask>unamb</hask> was originally a part of [[Reactive]].  I moved it to its own package in order to encourage experimentation.  Besides this wiki page, here are more ways to find out about unamb:-* Read [http://code.haskell.org/unamb/doc/html/ the library documentation].-* Get the code repository: '''<tt>darcs get http://code.haskell.org/unamb</tt>'''.-* Install from [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unamb Hackage].-* See the [[unamb/Versions| version history]].+* Visit the [http://hackage.haskell.org/cgi-bin/hackage-scripts/package/unamb Hackage page] for library documentation and to download & install.+* Or install with <tt>cabal install unamb</tt>.+* Get the code repository: <tt>darcs get http://code.haskell.org/unamb</tt>.+<!-- * See the [[unamb/Versions| version history]]. -->  Please leave comments at the [[Talk:unamb|Talk page]].