dunai 0.1.1.0 → 0.2.0.0
raw patch · 21 files changed
+255/−153 lines, 21 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
- Control.Monad.Trans.MSF.Except: instance GHC.Base.Functor (Control.Monad.Trans.MSF.Except.MSFExcept m a b)
- Data.MonadicStreamFunction.ArrowChoice: instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Data.MonadicStreamFunction.Core.MSF m)
- Data.MonadicStreamFunction.ArrowLoop: instance (GHC.Base.Monad m, Control.Monad.Fix.MonadFix m) => Control.Arrow.ArrowLoop (Data.MonadicStreamFunction.Core.MSF m)
- Data.MonadicStreamFunction.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowPlus (Data.MonadicStreamFunction.Core.MSF m)
- Data.MonadicStreamFunction.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowZero (Data.MonadicStreamFunction.Core.MSF m)
- Data.MonadicStreamFunction.Instances: elementwise :: Monad m => (b -> c) -> MSF m a b -> MSF m a c
- Data.MonadicStreamFunction.Instances: elementwise2 :: Monad m => (b -> c -> d) -> MSF m a b -> MSF m a c -> MSF m a d
+ Control.Monad.Trans.MSF.Except: currentInput :: Monad m => MSFExcept m e b e
+ Control.Monad.Trans.MSF.Except: instance GHC.Base.Monad m => GHC.Base.Functor (Control.Monad.Trans.MSF.Except.MSFExcept m a b)
+ Control.Monad.Trans.MSF.Except: maybeToExceptS :: Monad m => MSF (MaybeT m) a b -> MSF (ExceptT () m) a b
+ Control.Monad.Trans.MSF.Except: step :: Monad m => (a -> m (b, e)) -> MSFExcept m a b e
+ Control.Monad.Trans.MSF.Maybe: listToMaybeS :: Monad m => [b] -> MSF (MaybeT m) a b
+ Data.MonadicStreamFunction.Async: concatS :: Monad m => MStream m [b] -> MStream m b
+ Data.MonadicStreamFunction.Instances.ArrowChoice: instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Data.MonadicStreamFunction.Core.MSF m)
+ Data.MonadicStreamFunction.Instances.ArrowLoop: instance (GHC.Base.Monad m, Control.Monad.Fix.MonadFix m) => Control.Arrow.ArrowLoop (Data.MonadicStreamFunction.Core.MSF m)
+ Data.MonadicStreamFunction.Instances.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowPlus (Data.MonadicStreamFunction.Core.MSF m)
+ Data.MonadicStreamFunction.Instances.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowZero (Data.MonadicStreamFunction.Core.MSF m)
- Control.Monad.Trans.MSF.Except: once :: Monad m => (a -> m b) -> MSFExcept m a c ()
+ Control.Monad.Trans.MSF.Except: once :: Monad m => (a -> m e) -> MSFExcept m a b e
- Control.Monad.Trans.MSF.Except: once_ :: Monad m => m b -> MSFExcept m c d ()
+ Control.Monad.Trans.MSF.Except: once_ :: Monad m => m e -> MSFExcept m a b e
Files
- dunai.cabal +5/−6
- src/Control/Arrow/Util.hs +7/−0
- src/Control/Monad/Trans/MSF.hs +18/−9
- src/Control/Monad/Trans/MSF/Except.hs +34/−17
- src/Control/Monad/Trans/MSF/Maybe.hs +10/−8
- src/Control/Monad/Trans/MSF/Writer.hs +1/−1
- src/Data/MonadicStreamFunction.hs +13/−6
- src/Data/MonadicStreamFunction/ArrowChoice.hs +0/−13
- src/Data/MonadicStreamFunction/ArrowLoop.hs +0/−15
- src/Data/MonadicStreamFunction/ArrowPlus.hs +0/−13
- src/Data/MonadicStreamFunction/Async.hs +62/−0
- src/Data/MonadicStreamFunction/Core.hs +35/−31
- src/Data/MonadicStreamFunction/Instances.hs +0/−15
- src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs +18/−0
- src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs +21/−0
- src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs +18/−0
- src/Data/MonadicStreamFunction/Instances/Num.hs +0/−1
- src/Data/MonadicStreamFunction/Instances/VectorSpace.hs +4/−4
- src/Data/MonadicStreamFunction/Parallel.hs +8/−6
- src/Data/MonadicStreamFunction/Util.hs +1/−1
- src/Data/Tuple/Util.hs +0/−7
dunai.cabal view
@@ -1,5 +1,5 @@ name: dunai-version: 0.1.1.0+version: 0.2.0.0 synopsis: Generalised reactive framework supporting classic, arrowized and monadic FRP. description: Dunai is DSL for strongly-typed CPS-based composable transformations.@@ -60,10 +60,10 @@ Control.Monad.Trans.MSF.Writer Data.MonadicStreamFunction Data.MonadicStreamFunction.Core- Data.MonadicStreamFunction.ArrowChoice- Data.MonadicStreamFunction.ArrowLoop- Data.MonadicStreamFunction.ArrowPlus- Data.MonadicStreamFunction.Instances+ Data.MonadicStreamFunction.Async+ Data.MonadicStreamFunction.Instances.ArrowChoice+ Data.MonadicStreamFunction.Instances.ArrowLoop+ Data.MonadicStreamFunction.Instances.ArrowPlus Data.MonadicStreamFunction.Instances.Num Data.MonadicStreamFunction.Instances.VectorSpace Data.MonadicStreamFunction.Parallel@@ -77,7 +77,6 @@ Data.VectorSpace.Specific other-modules: Control.Arrow.Util- Data.Tuple.Util build-depends: base >=4.6 && < 5, transformers,
src/Control/Arrow/Util.hs view
@@ -26,3 +26,10 @@ -- sink :: Arrow a => a b c -> a c () -> a b c -- a1 `sink` a2 = a1 >>> (id &&& a2) >>> arr fst++-- Apply functions at the end+elementwise :: Arrow a => (c -> d) -> a b c -> a b d+elementwise = (^<<)++elementwise2 :: Arrow a => (c -> d -> e) -> a b c -> a b d -> a b e+elementwise2 op a1 a2 = (a1 &&& a2) >>^ uncurry op
src/Control/Monad/Trans/MSF.hs view
@@ -1,12 +1,21 @@-{-# LANGUAGE Rank2Types #-}+{-# LANGUAGE Rank2Types #-} -module Control.Monad.Trans.MSF ( module X ) where--- Caution, RWS is not exported since names collide with Reader, State and Writer+module Control.Monad.Trans.MSF+ ( module Control.Monad.Trans.MSF.GenLift+ , module Control.Monad.Trans.MSF.Except+ , module Control.Monad.Trans.MSF.Maybe+ , module Control.Monad.Trans.MSF.Reader+ , module Control.Monad.Trans.MSF.State+ , module Control.Monad.Trans.MSF.Writer+ )+ where -import Control.Monad.Trans.MSF.GenLift as X+-- Caution: RWS is not exported since names collide with Reader, State and+-- Writer -import Control.Monad.Trans.MSF.Except as X-import Control.Monad.Trans.MSF.Maybe as X-import Control.Monad.Trans.MSF.Reader as X-import Control.Monad.Trans.MSF.State as X-import Control.Monad.Trans.MSF.Writer as X+import Control.Monad.Trans.MSF.GenLift+import Control.Monad.Trans.MSF.Except+import Control.Monad.Trans.MSF.Maybe+import Control.Monad.Trans.MSF.Reader+import Control.Monad.Trans.MSF.State+import Control.Monad.Trans.MSF.Writer
src/Control/Monad/Trans/MSF/Except.hs view
@@ -6,17 +6,17 @@ ) where -- External-import Control.Applicative-import qualified Control.Category as Category-import Control.Monad.Trans.Class-import Control.Monad.Trans.Except- hiding (liftCallCC, liftListen, liftPass) -- Avoid conflicting exports+import Control.Applicative+import qualified Control.Category as Category+import Control.Monad (liftM, ap)+import Control.Monad.Trans.Class+import Control.Monad.Trans.Except hiding (liftCallCC, liftListen, liftPass) -- Avoid conflicting exports+import Control.Monad.Trans.Maybe -- Internal-import Control.Monad.Trans.MSF.GenLift+-- import Control.Monad.Trans.MSF.GenLift import Data.MonadicStreamFunction - -- * Throwing exceptions throwOnCond :: Monad m => (a -> Bool) -> e -> MSF (ExceptT e m) a a@@ -28,9 +28,8 @@ throwOnCondM cond e = proc a -> do b <- arrM (lift . cond) -< a if b- then arrM throwE -< e- else returnA -< a-+ then arrM throwE -< e+ else returnA -< a throwOn :: Monad m => e -> MSF (ExceptT e m) Bool () throwOn e = proc b -> throwOn' -< (b, e)@@ -52,6 +51,10 @@ pass :: Monad m => MSF (ExceptT e m) a a pass = Category.id +-- | Whenever 'Nothing' is thrown, throw '()' instead.+maybeToExceptS :: Monad m => MSF (MaybeT m) a b -> MSF (ExceptT () m) a b+maybeToExceptS = liftMSFPurer (ExceptT . (maybe (Left ()) Right <$>) . runMaybeT)+ -- * Catching exceptions {-@@ -89,8 +92,6 @@ Left e -> return (Left e, go) Right (b, msf') -> return (Right b, exceptS msf') -- inExceptT :: Monad m => MSF (ExceptT e m) (ExceptT e m a) a inExceptT = arrM id -- extracts value from monadic action @@ -102,6 +103,7 @@ Left e -> _ return t Right bmsf' -> _ return bmsf' -}+ -- * Monad interface for Exception MSFs newtype MSFExcept m a b e = MSFExcept { runMSFExcept :: MSF (ExceptT e m) a b }@@ -109,10 +111,16 @@ try :: MSF (ExceptT e m) a b -> MSFExcept m a b e try = MSFExcept -instance Functor (MSFExcept m a b) where+-- | Immediately throw the current input as an exception.+currentInput :: Monad m => MSFExcept m e b e+currentInput = try throwS +instance Monad m => Functor (MSFExcept m a b) where+ fmap = liftM+ instance Monad m => Applicative (MSFExcept m a b) where pure = MSFExcept . throw+ (<*>) = ap instance Monad m => Monad (MSFExcept m a b) where MSFExcept msf >>= f = MSFExcept $ MSF $ \a -> do@@ -133,15 +141,24 @@ safe :: Monad m => MSF m a b -> MSFExcept m a b e safe = try . liftMSFTrans -once :: Monad m => (a -> m b) -> MSFExcept m a c ()-once f = MSFExcept $ arrM (lift . f) >>> throw ()+once :: Monad m => (a -> m e) -> MSFExcept m a b e+once f = try $ arrM (lift . f) >>> throwS -once_ :: Monad m => m b -> MSFExcept m c d ()+once_ :: Monad m => m e -> MSFExcept m a b e once_ = once . const +-- | Advances a single tick with the given Kleisli arrow,+-- and then throws an exception.+step :: Monad m => (a -> m (b, e)) -> MSFExcept m a b e+step f = try $ proc a -> do+ n <- count -< ()+ (b, e) <- arrM (lift . f) -< a+ _ <- throwOn' -< (n > (1 :: Int), e)+ returnA -< b+ tagged :: Monad m => MSF (ExceptT e1 m) a b -> MSF (ExceptT e2 m) (a, e2) b tagged msf = MSF $ \(a, e2) -> ExceptT $ do cont <- runExceptT $ unMSF msf a case cont of- Left e1 -> return $ Left e2+ Left _e1 -> return $ Left e2 Right (b, msf') -> return $ Right (b, tagged msf')
src/Control/Monad/Trans/MSF/Maybe.hs view
@@ -13,7 +13,6 @@ import Control.Monad.Trans.MSF.GenLift import Data.MonadicStreamFunction - runMaybeS'' :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b) runMaybeS'' = transG transformInput transformOutput where@@ -30,11 +29,10 @@ exit = MSF $ const $ MaybeT $ return Nothing exitWhen :: Monad m => (a -> Bool) -> MSF (MaybeT m) a a-exitWhen condition = go where- go = MSF $ \a -> MaybeT $- if condition a- then return Nothing- else return $ Just (a, go)+exitWhen condition = go+ where+ go = MSF $ \a -> MaybeT $ return $+ if condition a then Nothing else Just (a, go) exitIf :: Monad m => MSF (MaybeT m) Bool () exitIf = MSF $ \b -> MaybeT $ return $ if b then Nothing else Just ((), exitIf)@@ -61,8 +59,13 @@ Just (b, msf1') -> return (b, msf1' `catchMaybe` msf2) Nothing -> unMSF msf2 a -+-- * Converting to and from 'MaybeT' +-- | Converts a list to an 'MSF' in 'MaybeT',+-- which outputs an element of the list at each step,+-- throwing 'Nothing' when the list ends.+listToMaybeS :: Monad m => [b] -> MSF (MaybeT m) a b+listToMaybeS = foldr iPost exit -- * Running MaybeT runMaybeS :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)@@ -73,7 +76,6 @@ case bmsf of Just (b, msf') -> return (Just b, runMaybeS msf') Nothing -> return (Nothing, go)- -- mapMaybeS msf == runMaybeS (inMaybeT >>> lift mapMaybeS)
src/Control/Monad/Trans/MSF/Writer.hs view
@@ -8,7 +8,7 @@ import Control.Monad.Trans.Class import Control.Monad.Trans.Writer.Strict hiding (liftCallCC, liftCatch, pass) -- Avoid conflicting exports-import Data.Monoid+-- import Data.Monoid -- Internal import Control.Monad.Trans.MSF.GenLift
src/Data/MonadicStreamFunction.hs view
@@ -28,10 +28,17 @@ -- For a very detailed introduction to MSFs, see: -- <http://dl.acm.org/citation.cfm?id=2976010> -- (mirror: <http://www.cs.nott.ac.uk/~psxip1/#FRPRefactored>).+--+-- Apart from the modules exported, this module exports instances from:+--+-- - "Data.MonadicStreamFunction.Instances.ArrowChoice"+-- - "Data.MonadicStreamFunction.Instances.ArrowLoop"+-- - "Data.MonadicStreamFunction.Instances.ArrowPlus" module Data.MonadicStreamFunction ( module Control.Arrow- , module X+ , module Data.MonadicStreamFunction.Core+ , module Data.MonadicStreamFunction.Util ) where @@ -41,11 +48,11 @@ -- Internal -import Data.MonadicStreamFunction.Core as X-import Data.MonadicStreamFunction.Util as X+import Data.MonadicStreamFunction.Core+import Data.MonadicStreamFunction.Util -- Internal (Instances) -import Data.MonadicStreamFunction.ArrowChoice ()-import Data.MonadicStreamFunction.ArrowLoop ()-import Data.MonadicStreamFunction.ArrowPlus ()+import Data.MonadicStreamFunction.Instances.ArrowChoice ()+import Data.MonadicStreamFunction.Instances.ArrowLoop ()+import Data.MonadicStreamFunction.Instances.ArrowPlus ()
− src/Data/MonadicStreamFunction/ArrowChoice.hs
@@ -1,13 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Data.MonadicStreamFunction.ArrowChoice where--import Control.Arrow--import Data.MonadicStreamFunction.Core--instance Monad m => ArrowChoice (MSF m) where- left sf = MSF f- where- f (Left a) = do (b, sf') <- unMSF sf a- return (Left b, left sf')- f (Right c) = return (Right c, left sf)
− src/Data/MonadicStreamFunction/ArrowLoop.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE RecursiveDo #-}-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Data.MonadicStreamFunction.ArrowLoop where--import Data.MonadicStreamFunction.Core---- External-import Control.Arrow-import Control.Monad.Fix--instance (Monad m, MonadFix m) => ArrowLoop (MSF m) where- -- loop :: a (b, d) (c, d) -> a b c- loop sf = MSF $ \a -> do- rec ((b,c), sf') <- unMSF sf (a, c)- return (b, loop sf')
− src/Data/MonadicStreamFunction/ArrowPlus.hs
@@ -1,13 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-module Data.MonadicStreamFunction.ArrowPlus where--import Control.Arrow-import Control.Monad--import Data.MonadicStreamFunction.Core--instance (Monad m, MonadPlus m) => ArrowZero (MSF m) where- zeroArrow = MSF $ const mzero--instance (Monad m, MonadPlus m) => ArrowPlus (MSF m) where- sf1 <+> sf2 = MSF $ \a -> unMSF sf1 a `mplus` unMSF sf2 a
+ src/Data/MonadicStreamFunction/Async.hs view
@@ -0,0 +1,62 @@+-- | This module contains operations on monadic streams that are asynchronous,+-- i.e. that change the speed at which data enters or leaves the 'MSF'.++module Data.MonadicStreamFunction.Async where++-- Internal+import Data.MonadicStreamFunction.Core+import Data.MonadicStreamFunction.Util (MStream)++{- |+Concatenates a monadic stream of lists to a monadic stream.+The stream of lists will be called exactly when new data is needed.++Example:++>>> let intstream = concatS $ arrM_ $ putStrLn "Enter a list of Ints:" >> readLn :: MStream IO Int+>>> reactimate $ concatS intstream >>> arrM print+Enter a list of Ints:+[1,2,33]+1+2+33+Enter a list of Ints:+[]+Enter a list of Ints:+[]+Enter a list of Ints:+[1,2]+1+2+Enter a list of Ints:+...++Beware that @concatS msf@ becomes unproductive when @msf@ starts outputting empty lists forever.+This is ok:++>>> let boolToList b = if b then ["Yes"] else []+>>> let everyOddEmpty = count >>> arr (even >>> boolToList)+>>> reactimate $ concatS everyOddEmpty >>> arrM print+"Yes"+"Yes"+"Yes"+"Yes"+"Yes"+...++But this will be caught in a loop:++>>> let after3Empty = count >>> arr ((<= 3) >>> boolToList)+reactimate $ concatS after3Empty >>> arrM print+"Yes"+"Yes"+"Yes"+^CInterrupted.+-}+concatS :: Monad m => MStream m [b] -> MStream m b+concatS msf = MSF $ \_ -> tick msf []+ where+ tick msf' (b:bs) = return (b, MSF $ \_ -> tick msf' bs)+ tick msf' [] = do+ (bs, msf'') <- unMSF msf' ()+ tick msf'' bs
src/Data/MonadicStreamFunction/Core.hs view
@@ -100,24 +100,46 @@ pure = arr . const fs <*> bs = (fs &&& bs) >>> arr (uncurry ($)) --- * Lifting+-- * Monadic computations and MSFs --- | Apply the same monadic transformation to every element of the input stream.+-- ** Lifting point-wise computations++-- | Apply a monadic transformation to every element of the input stream. ----- Generalisation of arr from Arrow to stream functions with monads.+-- Generalisation of 'arr' from 'Arrow' to monadic functions. arrM :: Monad m => (a -> m b) -> MSF m a b arrM f = go where go = MSF $ \a -> do b <- f a return (b, go) --- * Monadic lifting from one monad into another-+-- | Monadic lifting from one monad into another liftS :: (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b liftS = arrM . (liftBase .) --- ** Purer monads+-- ** Lifting MSFs +-- *** Lifting across monad stacks++-- | Lift inner monadic actions in monad stacks.++-- TODO Should be able to express this in terms of MonadBase+liftMSFTrans :: (MonadTrans t, Monad m, Monad (t m))+ => MSF m a b+ -> MSF (t m) a b+liftMSFTrans sf = MSF $ \a -> do+ (b, sf') <- lift $ unMSF sf a+ return (b, liftMSFTrans sf')++-- | Lift innermost monadic actions in a monad stacks (generalisation of+-- 'liftIO').+liftMSFBase :: (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b+liftMSFBase sf = MSF $ \a -> do+ (b, sf') <- liftBase $ unMSF sf a+ b `seq` return (b, liftMSFBase sf')++-- *** Generic MSF Lifting+ -- IPerez: There is an alternative signature for liftMStreamPurer that also -- works, and makes the code simpler: --@@ -141,26 +163,7 @@ (b, sf') <- liftPurer $ unMSF sf a b `seq` return (b, liftMSFPurer liftPurer sf') --- ** Monad stacks---- | Lift inner monadic actions in monad stacks.---- TODO Should be able to express this in terms of MonadBase-liftMSFTrans :: (MonadTrans t, Monad m, Monad (t m))- => MSF m a b- -> MSF (t m) a b-liftMSFTrans sf = MSF $ \a -> do- (b, sf') <- lift $ unMSF sf a- return (b, liftMSFTrans sf')---- | Lift innermost monadic actions in a monad stacks (generalisation of--- 'liftIO').-liftMSFBase :: (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b-liftMSFBase sf = MSF $ \a -> do- (b, sf') <- liftBase $ unMSF sf a- b `seq` return (b, liftMSFBase sf')---- * MSFs within monadic actions+-- ** MSFs within monadic actions -- | Extract MSF from a monadic action. --@@ -172,7 +175,7 @@ sf <- sfaction unMSF sf a --- ** Delays and signal overwriting+-- * Delays -- | Delay a signal by one sample. iPre :: Monad m@@ -190,7 +193,7 @@ delay :: Monad m => a -> MSF m a a delay = iPre --- ** Switching+-- * Switching -- | Switching applies one MSF until it produces a 'Just' output, and then -- "turns on" a continuation and runs it.@@ -202,7 +205,7 @@ ((b, c), sf') <- unMSF sf a return (b, maybe (switch sf' f) f c) --- ** Feedback loops+-- * Feedback loops -- | Well-formed looped connection of an output component as a future input. feedback :: Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b@@ -239,8 +242,9 @@ reactimate sf' -- | Run an MSF indefinitely passing a unit-carrying input stream.--- A more high-level approach to this would be the use of MaybeT--- in Control.Monad.Trans.MSF.Maybe++-- TODO: A more high-level approach to this would be the use of MaybeT in+-- Control.Monad.Trans.MSF.Maybe reactimateB :: Monad m => MSF m () Bool -> m () reactimateB sf = do (b, sf') <- unMSF sf ()
− src/Data/MonadicStreamFunction/Instances.hs
@@ -1,15 +0,0 @@-{-# LANGUAGE TypeFamilies #-}-module Data.MonadicStreamFunction.Instances where---- External-import Control.Arrow---- Internal-import Data.MonadicStreamFunction.Core---- Numerical operations are defined elementwise on the output-elementwise :: Monad m => (b -> c) -> MSF m a b -> MSF m a c-elementwise f msf = msf >>> arr f--elementwise2 :: Monad m => (b -> c -> d) -> MSF m a b -> MSF m a c -> MSF m a d-elementwise2 op msf1 msf2 = msf1 &&& msf2 >>> arr (uncurry op)
+ src/Data/MonadicStreamFunction/Instances/ArrowChoice.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE InstanceSigs #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- | Instance of 'ArrowChoice' for Monadic Stream Functions ('MSF').+--+-- Import this module to include that (orphan) instance.+module Data.MonadicStreamFunction.Instances.ArrowChoice where++import Control.Arrow++import Data.MonadicStreamFunction.Core++instance Monad m => ArrowChoice (MSF m) where+ left :: MSF m a b -> MSF m (Either a c) (Either b c)+ left sf = MSF f+ where+ f (Left a) = do (b, sf') <- unMSF sf a+ return (Left b, left sf')+ f (Right c) = return (Right c, left sf)
+ src/Data/MonadicStreamFunction/Instances/ArrowLoop.hs view
@@ -0,0 +1,21 @@+{-# LANGUAGE InstanceSigs #-}+{-# LANGUAGE RecursiveDo #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- | Instance of 'ArrowLoop' for Monadic Stream Functions ('MSF').+--+-- Import this module to include that (orphan) instance.+--+-- This is only defined for monads that are instances of 'MonadFix'.+module Data.MonadicStreamFunction.Instances.ArrowLoop where++import Data.MonadicStreamFunction.Core++-- External+import Control.Arrow+import Control.Monad.Fix++instance (Monad m, MonadFix m) => ArrowLoop (MSF m) where+ loop :: MSF m (b, d) (c, d) -> MSF m b c+ loop sf = MSF $ \a -> do+ rec ((b,c), sf') <- unMSF sf (a, c)+ return (b, loop sf')
+ src/Data/MonadicStreamFunction/Instances/ArrowPlus.hs view
@@ -0,0 +1,18 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- | Instance of 'ArrowPlus' for Monadic Stream Functions ('MSF').+--+-- Import this module to include that (orphan) instance.+--+-- This is only defined for monads that are instances of 'MonadPlus'.+module Data.MonadicStreamFunction.Instances.ArrowPlus where++import Control.Arrow+import Control.Monad++import Data.MonadicStreamFunction.Core++instance (Monad m, MonadPlus m) => ArrowZero (MSF m) where+ zeroArrow = MSF $ const mzero++instance (Monad m, MonadPlus m) => ArrowPlus (MSF m) where+ sf1 <+> sf2 = MSF $ \a -> unMSF sf1 a `mplus` unMSF sf2 a
src/Data/MonadicStreamFunction/Instances/Num.hs view
@@ -4,7 +4,6 @@ import Control.Arrow.Util import Data.MonadicStreamFunction.Core-import Data.MonadicStreamFunction.Instances instance (Monad m, Num b) => Num (MSF m a b) where (+) = elementwise2 (+)
src/Data/MonadicStreamFunction/Instances/VectorSpace.hs view
@@ -2,19 +2,19 @@ {-# OPTIONS_GHC -fno-warn-orphans #-} module Data.MonadicStreamFunction.Instances.VectorSpace where +import Control.Arrow import Control.Arrow.Util import Data.MonadicStreamFunction.Core-import Data.MonadicStreamFunction.Instances import Data.VectorSpace -- These conflict with Data.VectorSpace.Instances instance (Monad m, RModule v) => RModule (MSF m a v) where type Groundring (MSF m a v) = Groundring v zeroVector = constantly zeroVector- r *^ msf = elementwise (r *^) msf- negateVector = elementwise negateVector+ r *^ msf = msf >>^ (r *^)+ negateVector = (>>^ negateVector) (^+^) = elementwise2 (^+^) (^-^) = elementwise2 (^-^) instance (Monad m, VectorSpace v) => VectorSpace (MSF m a v) where- msf ^/ r = elementwise (^/ r) msf+ msf ^/ r = msf >>^ (^/ r)
src/Data/MonadicStreamFunction/Parallel.hs view
@@ -2,12 +2,14 @@ -- External import Control.Arrow--- import Control.Parallel import GHC.Conc -- Internal import Data.MonadicStreamFunction +-- | Run two MSFs in parallel, taking advantage of parallelism if+-- possible. This is the parallel version of '(***)'.+ -- IPerez: This should be similar to the following: -- (msf1 *** msf2) >>> parS -- where parS = arr parTuple@@ -15,13 +17,13 @@ -- Manuel: but we added strictness annotations to first -- and so (***) might be strict in both arguments and not take -- full advantage of parallelism.---+ (*|*) :: Monad m => MSF m a b -> MSF m c d -> MSF m (a, c) (b, d) msf1 *|* msf2 = MSF $ \(a, c) -> do- (b, msf1') <- unMSF msf1 a- (d, msf2') <- unMSF msf2 c- b `par` d `pseq` return ((b, d), msf1' *|* msf2')-+ (b, msf1') <- unMSF msf1 a+ (d, msf2') <- unMSF msf2 c+ b `par` d `pseq` return ((b, d), msf1' *|* msf2') +-- | Parallel version of '(&&&)'. (&|&) :: Monad m => MSF m a b -> MSF m a c -> MSF m a (b, c) msf1 &|& msf2 = arr (\a -> (a, a)) >>> (msf1 *|* msf2)
src/Data/MonadicStreamFunction/Util.hs view
@@ -56,7 +56,7 @@ where repeatedly' a = MSF $ \() -> let a' = f a in a' `seq` return (a, repeatedly' a') -- repeatedly f x = feedback x (arr (f >>> \x -> (x,x))) --- * Special cases of map+-- * Analogues of map and fmap mapMSF :: Monad m => MSF m a b -> MSF m [a] [b] mapMSF = MSF . consume
− src/Data/Tuple/Util.hs
@@ -1,7 +0,0 @@-module Data.Tuple.Util where--assocR :: ((a, b), c) -> (a, (b, c))-assocR ((a, b), c) = (a, (b, c))--assocL :: (a, (b, c)) -> ((a, b), c)-assocL (a, (b, c)) = ((a, b), c)