summaryrefslogtreecommitdiff
path: root/Reactor/Observer.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Reactor/Observer.hs')
-rw-r--r--Reactor/Observer.hs38
1 files changed, 38 insertions, 0 deletions
diff --git a/Reactor/Observer.hs b/Reactor/Observer.hs
new file mode 100644
index 0000000..58e5923
--- /dev/null
+++ b/Reactor/Observer.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+module Reactor.Observer
+ ( Observer(..)
+ , (?!)
+ ) where
+
+import Prelude hiding (filter)
+import Control.Monad
+import Control.Exception hiding (handle)
+import Control.Monad.Error
+import Data.Monoid
+import Data.Functor.Contravariant
+import Data.Data
+import Reactor.Filtered
+import Reactor.Task
+
+data Observer a = Observer
+ { (!) :: a -> Task ()
+ , handle :: SomeException -> Task ()
+ , complete :: Task ()
+ } deriving Typeable
+
+instance Contravariant Observer where
+ contramap g (Observer f h c) = Observer (f . g) h c
+
+instance Filtered Observer where
+ filter p (Observer f h c) = Observer (\a -> when (p a) (f a)) h c
+
+instance Monoid (Observer a) where
+ mempty = Observer (\_ -> return ()) throwError (return ())
+ p `mappend` q = Observer
+ (\a -> do p ! a; q ! a)
+ (\e -> do handle p e; handle q e)
+ (do complete p; complete q)
+
+-- filter and map in one operation
+(?!) :: Observer b -> (a -> Maybe b) -> Observer a
+Observer f h c ?! p = Observer (maybe (return ()) f . p) h c