packages feed

dunai 0.1.0.0 → 0.1.1.0

raw patch · 25 files changed

+1130/−833 lines, 25 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Control.Monad.Trans.MStreamF: catchMaybe :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a b -> MStreamF m a b
- Control.Monad.Trans.MStreamF: catchS :: Monad m => MStreamF (ExceptT e m) a b -> (e -> MStreamF m a b) -> MStreamF m a b
- Control.Monad.Trans.MStreamF: exceptS :: Monad m => MStreamF (ExceptT e m) a b -> MStreamF m a (Either e b)
- Control.Monad.Trans.MStreamF: exit :: Monad m => MStreamF (MaybeT m) a b
- Control.Monad.Trans.MStreamF: exitIf :: Monad m => MStreamF (MaybeT m) Bool ()
- Control.Monad.Trans.MStreamF: exitWhen :: Monad m => (a -> Bool) -> MStreamF (MaybeT m) a a
- Control.Monad.Trans.MStreamF: inExceptT :: Monad m => MStreamF (ExceptT e m) (ExceptT e m a) a
- Control.Monad.Trans.MStreamF: inMaybeT :: Monad m => MStreamF (MaybeT m) (Maybe a) a
- Control.Monad.Trans.MStreamF: lifterS :: (Monad m, Monad m1) => ((a1 -> m1 (b1, MStreamF m1 a1 b1)) -> a -> m (b, MStreamF m1 a1 b1)) -> MStreamF m1 a1 b1 -> MStreamF m a b
- Control.Monad.Trans.MStreamF: mapMaybeS :: Monad m => MStreamF m a b -> MStreamF m (Maybe a) (Maybe b)
- Control.Monad.Trans.MStreamF: maybeExit :: Monad m => MStreamF (MaybeT m) (Maybe a) a
- Control.Monad.Trans.MStreamF: readerS :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b
- Control.Monad.Trans.MStreamF: readerS' :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b
- Control.Monad.Trans.MStreamF: runMaybeS :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)
- Control.Monad.Trans.MStreamF: runMaybeS'' :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)
- Control.Monad.Trans.MStreamF: runRWSS :: (Functor m, Monad m, Monoid w) => MStreamF (RWST r w s m) a b -> MStreamF m (r, s, a) (w, s, b)
- Control.Monad.Trans.MStreamF: runReaderS :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b
- Control.Monad.Trans.MStreamF: runReaderS' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b
- Control.Monad.Trans.MStreamF: runReaderS'' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b
- Control.Monad.Trans.MStreamF: runReaderS_ :: Monad m => MStreamF (ReaderT s m) a b -> s -> MStreamF m a b
- Control.Monad.Trans.MStreamF: runStateS :: Monad m => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
- Control.Monad.Trans.MStreamF: runStateS' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
- Control.Monad.Trans.MStreamF: runStateS'' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
- Control.Monad.Trans.MStreamF: runStateS''' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)
- Control.Monad.Trans.MStreamF: runStateS_ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a (s, b)
- Control.Monad.Trans.MStreamF: runStateS__ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a b
- Control.Monad.Trans.MStreamF: runWriterS :: Monad m => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)
- Control.Monad.Trans.MStreamF: runWriterS' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)
- Control.Monad.Trans.MStreamF: runWriterS'' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)
- Control.Monad.Trans.MStreamF: sequenceS :: Monad m => [MStreamF m a b] -> MStreamF (ListT m) a b
- Control.Monad.Trans.MStreamF: stateS :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b
- Control.Monad.Trans.MStreamF: stateS' :: (Functor m, Monad m) => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b
- Control.Monad.Trans.MStreamF: throwMaybe :: Monad m => MStreamF (ExceptT e m) (Maybe e) (Maybe a)
- Control.Monad.Trans.MStreamF: throwOn :: Monad m => e -> MStreamF (ExceptT e m) Bool ()
- Control.Monad.Trans.MStreamF: throwOn' :: Monad m => MStreamF (ExceptT e m) (Bool, e) ()
- Control.Monad.Trans.MStreamF: throwOnCond :: Monad m => (a -> Bool) -> e -> MStreamF (ExceptT e m) a a
- Control.Monad.Trans.MStreamF: throwOnCondM :: Monad m => (a -> m Bool) -> e -> MStreamF (ExceptT e m) a a
- Control.Monad.Trans.MStreamF: throwS :: Monad m => MStreamF (ExceptT e m) e a
- Control.Monad.Trans.MStreamF: transG :: (Monad m1, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c)) -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2
- Control.Monad.Trans.MStreamF: transG1 :: (Monad m1, Functor m2, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c)) -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2
- Control.Monad.Trans.MStreamF: transS :: (Monad m1, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c)) -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2
- Control.Monad.Trans.MStreamF: type Id a = a
- Control.Monad.Trans.MStreamF: type ReaderUnwrapper s m = Unwrapper (ReaderT s m) m ((,) s) Id
- Control.Monad.Trans.MStreamF: type ReaderWrapper s m = Wrapper (ReaderT s m) m ((,) s) Id
- Control.Monad.Trans.MStreamF: type Unwrapper m1 m2 t1 t2 = forall a b. (a -> m1 (t2 b)) -> (t1 a -> m2 b)
- Control.Monad.Trans.MStreamF: type Wrapper m1 m2 t1 t2 = forall a b. (t1 a -> m2 b) -> (a -> m1 (t2 b))
- Control.Monad.Trans.MStreamF: untilE :: Monad m => MStreamF m a b -> MStreamF m b (Maybe e) -> MStreamF (ExceptT e m) a b
- Control.Monad.Trans.MStreamF: untilMaybe :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF (MaybeT m) a b
- Control.Monad.Trans.MStreamF: unwrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)
- Control.Monad.Trans.MStreamF: unwrapReaderT :: (a -> ReaderT s m b) -> (s, a) -> m b
- Control.Monad.Trans.MStreamF: widthFirst :: (Functor m, Monad m) => MStreamF (ListT m) a b -> MStreamF m a [b]
- Control.Monad.Trans.MStreamF: wrapMSFWriterT :: (Monoid s, Monad m) => (a -> m ((s, b), ct)) -> a -> WriterT s m (b, ct)
- Control.Monad.Trans.MStreamF: wrapReaderT :: ((s, a) -> m b) -> a -> ReaderT s m b
- Control.Monad.Trans.MStreamF: writerS :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b
- Control.Monad.Trans.MStreamF: writerS' :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b
- Control.Monad.Trans.MStreamF: writerS'' :: (Monad m, Monoid w) => MStreamF m a (w, b) -> MStreamF (WriterT w m) a b
- Data.MonadicStreamFunction: (>>>^) :: MonadBase m1 m2 => MStreamF m2 a b -> MStreamF m1 b c -> MStreamF m2 a c
- Data.MonadicStreamFunction: (^>>>) :: MonadBase m1 m2 => MStreamF m1 a b -> MStreamF m2 b c -> MStreamF m2 a c
- Data.MonadicStreamFunction: andThen :: Monad m => MStreamF m a (b, Maybe ()) -> MStreamF m a b -> MStreamF m a b
- Data.MonadicStreamFunction: count :: (Num n, Monad m) => MStreamF m () n
- Data.MonadicStreamFunction: iPost :: Monad m => b -> MStreamF m a b -> MStreamF m a b
- Data.MonadicStreamFunction: insert :: Monad m => MStreamF m (m a) a
- Data.MonadicStreamFunction: instance GHC.Base.Applicative m => GHC.Base.Applicative (Data.MonadicStreamFunction.Core.MStreamF m r)
- Data.MonadicStreamFunction: instance GHC.Base.Functor m => GHC.Base.Functor (Data.MonadicStreamFunction.Core.MStreamF m r)
- Data.MonadicStreamFunction: liftMStreamF_ :: Monad m => m b -> MStreamF m a b
- Data.MonadicStreamFunction: mapMStreamF :: Monad m => MStreamF m a b -> MStreamF m [a] [b]
- Data.MonadicStreamFunction: next :: Monad m => b -> MStreamF m a b -> MStreamF m a b
- Data.MonadicStreamFunction: pauseOn :: Show a => (a -> Bool) -> String -> MStreamF IO a a
- Data.MonadicStreamFunction: pauseOnGeneral :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MStreamF m a a
- Data.MonadicStreamFunction: repeatedly :: Monad m => (a -> a) -> a -> MStreamF m () a
- Data.MonadicStreamFunction: sum :: (Monoid n, Monad m) => MStreamF m n n
- Data.MonadicStreamFunction: sumFrom :: (Monoid n, Monad m) => n -> MStreamF m n n
- Data.MonadicStreamFunction: trace :: Show a => String -> MStreamF IO a a
- Data.MonadicStreamFunction: traceGeneral :: (Monad m, Show a) => (String -> m ()) -> String -> MStreamF m a a
- Data.MonadicStreamFunction: type MStream m a = MStreamF m () a
- Data.MonadicStreamFunction: unfold :: Monad m => (a -> (b, a)) -> a -> MStreamF m () b
- Data.MonadicStreamFunction: untilS :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF m a (b, Maybe ())
- Data.MonadicStreamFunction: withSideEffect :: Monad m => (a -> m b) -> MStreamF m a a
- Data.MonadicStreamFunction: withSideEffect_ :: Monad m => m b -> MStreamF m a a
- Data.MonadicStreamFunction.ArrowChoice: instance GHC.Base.Monad m => Control.Arrow.ArrowChoice (Data.MonadicStreamFunction.Core.MStreamF m)
- Data.MonadicStreamFunction.ArrowLoop: instance (GHC.Base.Monad m, Control.Monad.Fix.MonadFix m) => Control.Arrow.ArrowLoop (Data.MonadicStreamFunction.Core.MStreamF m)
- Data.MonadicStreamFunction.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowPlus (Data.MonadicStreamFunction.Core.MStreamF m)
- Data.MonadicStreamFunction.ArrowPlus: instance (GHC.Base.Monad m, GHC.Base.MonadPlus m) => Control.Arrow.ArrowZero (Data.MonadicStreamFunction.Core.MStreamF m)
- Data.MonadicStreamFunction.Core: MStreamF :: (a -> m (b, MStreamF m a b)) -> MStreamF m a b
- Data.MonadicStreamFunction.Core: [unMStreamF] :: MStreamF m a b -> a -> m (b, MStreamF m a b)
- Data.MonadicStreamFunction.Core: data MStreamF m a b
- Data.MonadicStreamFunction.Core: instance GHC.Base.Monad m => Control.Arrow.Arrow (Data.MonadicStreamFunction.Core.MStreamF m)
- Data.MonadicStreamFunction.Core: instance GHC.Base.Monad m => Control.Category.Category (Data.MonadicStreamFunction.Core.MStreamF m)
- Data.MonadicStreamFunction.Core: liftMStreamF :: Monad m => (a -> m b) -> MStreamF m a b
- Data.MonadicStreamFunction.Core: liftMStreamFBase :: (Monad m2, MonadBase m1 m2) => MStreamF m1 a b -> MStreamF m2 a b
- Data.MonadicStreamFunction.Core: liftMStreamFPurer :: (Monad m2, Monad m1) => (forall c. m1 c -> m2 c) -> MStreamF m1 a b -> MStreamF m2 a b
- Data.MonadicStreamFunction.Core: liftMStreamFTrans :: (MonadTrans t, Monad m, Monad (t m)) => MStreamF m a b -> MStreamF (t m) a b
- Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Float.Floating b) => GHC.Float.Floating (Data.MonadicStreamFunction.Core.MStreamF m a b)
- Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Num.Num b) => GHC.Num.Num (Data.MonadicStreamFunction.Core.MStreamF m a b)
- Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Real.Fractional b) => GHC.Real.Fractional (Data.MonadicStreamFunction.Core.MStreamF m a b)
- Data.MonadicStreamFunction.Instances.VectorSpace: instance (GHC.Base.Monad m, Data.VectorSpace.RModule v) => Data.VectorSpace.RModule (Data.MonadicStreamFunction.Core.MStreamF m a v)
- Data.MonadicStreamFunction.Instances.VectorSpace: instance (GHC.Base.Monad m, Data.VectorSpace.VectorSpace v) => Data.VectorSpace.VectorSpace (Data.MonadicStreamFunction.Core.MStreamF m a v)
- Data.VectorSpace.Instances: instance GHC.Num.Num a => Data.VectorSpace.InnerProductSpace a
- Data.VectorSpace.Instances: instance GHC.Num.Num a => Data.VectorSpace.RModule a
- Data.VectorSpace.Instances: instance GHC.Real.Fractional a => Data.VectorSpace.VectorSpace a
+ Control.Monad.Trans.MSF.Except: MSFExcept :: MSF (ExceptT e m) a b -> MSFExcept m a b e
+ Control.Monad.Trans.MSF.Except: [runMSFExcept] :: MSFExcept m a b e -> MSF (ExceptT e m) a b
+ Control.Monad.Trans.MSF.Except: catchS :: Monad m => MSF (ExceptT e m) a b -> (e -> MSF m a b) -> MSF m a b
+ Control.Monad.Trans.MSF.Except: data Empty
+ Control.Monad.Trans.MSF.Except: exceptS :: Monad m => MSF (ExceptT e m) a b -> MSF m a (Either e b)
+ Control.Monad.Trans.MSF.Except: inExceptT :: Monad m => MSF (ExceptT e m) (ExceptT e m a) a
+ Control.Monad.Trans.MSF.Except: instance GHC.Base.Functor (Control.Monad.Trans.MSF.Except.MSFExcept m a b)
+ Control.Monad.Trans.MSF.Except: instance GHC.Base.Monad m => GHC.Base.Applicative (Control.Monad.Trans.MSF.Except.MSFExcept m a b)
+ Control.Monad.Trans.MSF.Except: instance GHC.Base.Monad m => GHC.Base.Monad (Control.Monad.Trans.MSF.Except.MSFExcept m a b)
+ Control.Monad.Trans.MSF.Except: newtype MSFExcept m a b e
+ Control.Monad.Trans.MSF.Except: once :: Monad m => (a -> m b) -> MSFExcept m a c ()
+ Control.Monad.Trans.MSF.Except: once_ :: Monad m => m b -> MSFExcept m c d ()
+ Control.Monad.Trans.MSF.Except: pass :: Monad m => MSF (ExceptT e m) a a
+ Control.Monad.Trans.MSF.Except: safe :: Monad m => MSF m a b -> MSFExcept m a b e
+ Control.Monad.Trans.MSF.Except: safely :: Monad m => MSFExcept m a b Empty -> MSF m a b
+ Control.Monad.Trans.MSF.Except: tagged :: Monad m => MSF (ExceptT e1 m) a b -> MSF (ExceptT e2 m) (a, e2) b
+ Control.Monad.Trans.MSF.Except: throw :: Monad m => e -> MSF (ExceptT e m) a b
+ Control.Monad.Trans.MSF.Except: throwMaybe :: Monad m => MSF (ExceptT e m) (Maybe e) (Maybe a)
+ Control.Monad.Trans.MSF.Except: throwOn :: Monad m => e -> MSF (ExceptT e m) Bool ()
+ Control.Monad.Trans.MSF.Except: throwOn' :: Monad m => MSF (ExceptT e m) (Bool, e) ()
+ Control.Monad.Trans.MSF.Except: throwOnCond :: Monad m => (a -> Bool) -> e -> MSF (ExceptT e m) a a
+ Control.Monad.Trans.MSF.Except: throwOnCondM :: Monad m => (a -> m Bool) -> e -> MSF (ExceptT e m) a a
+ Control.Monad.Trans.MSF.Except: throwS :: Monad m => MSF (ExceptT e m) e a
+ Control.Monad.Trans.MSF.Except: try :: MSF (ExceptT e m) a b -> MSFExcept m a b e
+ Control.Monad.Trans.MSF.Except: untilE :: Monad m => MSF m a b -> MSF m b (Maybe e) -> MSF (ExceptT e m) a b
+ Control.Monad.Trans.MSF.GenLift: lifterS :: (Monad m, Monad m1) => ((a1 -> m1 (b1, MSF m1 a1 b1)) -> a -> m (b, MSF m1 a1 b1)) -> MSF m1 a1 b1 -> MSF m a b
+ Control.Monad.Trans.MSF.GenLift: transG :: (Monad m1, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c)) -> MSF m1 a1 b1 -> MSF m2 a2 b2
+ Control.Monad.Trans.MSF.GenLift: transG1 :: (Monad m1, Functor m2, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c)) -> MSF m1 a1 b1 -> MSF m2 a2 b2
+ Control.Monad.Trans.MSF.GenLift: transS :: (Monad m1, Monad m2) => (a2 -> m1 a1) -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c)) -> MSF m1 a1 b1 -> MSF m2 a2 b2
+ Control.Monad.Trans.MSF.GenLift: type Id a = a
+ Control.Monad.Trans.MSF.GenLift: type Unwrapper m1 m2 t1 t2 = forall a b. (a -> m1 (t2 b)) -> (t1 a -> m2 b)
+ Control.Monad.Trans.MSF.GenLift: type Wrapper m1 m2 t1 t2 = forall a b. (t1 a -> m2 b) -> (a -> m1 (t2 b))
+ Control.Monad.Trans.MSF.Maybe: catchMaybe :: Monad m => MSF (MaybeT m) a b -> MSF m a b -> MSF m a b
+ Control.Monad.Trans.MSF.Maybe: exit :: Monad m => MSF (MaybeT m) a b
+ Control.Monad.Trans.MSF.Maybe: exitIf :: Monad m => MSF (MaybeT m) Bool ()
+ Control.Monad.Trans.MSF.Maybe: exitWhen :: Monad m => (a -> Bool) -> MSF (MaybeT m) a a
+ Control.Monad.Trans.MSF.Maybe: inMaybeT :: Monad m => MSF (MaybeT m) (Maybe a) a
+ Control.Monad.Trans.MSF.Maybe: maybeExit :: Monad m => MSF (MaybeT m) (Maybe a) a
+ Control.Monad.Trans.MSF.Maybe: runMaybeS :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)
+ Control.Monad.Trans.MSF.Maybe: runMaybeS'' :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)
+ Control.Monad.Trans.MSF.Maybe: untilMaybe :: Monad m => MSF m a b -> MSF m b Bool -> MSF (MaybeT m) a b
+ Control.Monad.Trans.MSF.Reader: readerS :: Monad m => MSF m (s, a) b -> MSF (ReaderT s m) a b
+ Control.Monad.Trans.MSF.Reader: readerS' :: Monad m => MSF m (s, a) b -> MSF (ReaderT s m) a b
+ Control.Monad.Trans.MSF.Reader: runReaderS :: Monad m => MSF (ReaderT s m) a b -> MSF m (s, a) b
+ Control.Monad.Trans.MSF.Reader: runReaderS' :: Monad m => MSF (ReaderT s m) a b -> MSF m (s, a) b
+ Control.Monad.Trans.MSF.Reader: runReaderS'' :: Monad m => MSF (ReaderT s m) a b -> MSF m (s, a) b
+ Control.Monad.Trans.MSF.Reader: runReaderS_ :: Monad m => MSF (ReaderT s m) a b -> s -> MSF m a b
+ Control.Monad.Trans.MSF.Reader: type ReaderUnwrapper s m = Unwrapper (ReaderT s m) m ((,) s) Id
+ Control.Monad.Trans.MSF.Reader: type ReaderWrapper s m = Wrapper (ReaderT s m) m ((,) s) Id
+ Control.Monad.Trans.MSF.Reader: unwrapReaderT :: (a -> ReaderT s m b) -> (s, a) -> m b
+ Control.Monad.Trans.MSF.Reader: wrapReaderT :: ((s, a) -> m b) -> a -> ReaderT s m b
+ Control.Monad.Trans.MSF.State: runStateS :: Monad m => MSF (StateT s m) a b -> MSF m (s, a) (s, b)
+ Control.Monad.Trans.MSF.State: runStateS' :: (Functor m, Monad m) => MSF (StateT s m) a b -> MSF m (s, a) (s, b)
+ Control.Monad.Trans.MSF.State: runStateS'' :: (Functor m, Monad m) => MSF (StateT s m) a b -> MSF m (s, a) (s, b)
+ Control.Monad.Trans.MSF.State: runStateS''' :: (Functor m, Monad m) => MSF (StateT s m) a b -> MSF m (s, a) (s, b)
+ Control.Monad.Trans.MSF.State: runStateS_ :: Monad m => MSF (StateT s m) a b -> s -> MSF m a (s, b)
+ Control.Monad.Trans.MSF.State: runStateS__ :: Monad m => MSF (StateT s m) a b -> s -> MSF m a b
+ Control.Monad.Trans.MSF.State: stateS :: Monad m => MSF m (s, a) (s, b) -> MSF (StateT s m) a b
+ Control.Monad.Trans.MSF.State: stateS' :: (Functor m, Monad m) => MSF m (s, a) (s, b) -> MSF (StateT s m) a b
+ Control.Monad.Trans.MSF.Writer: runWriterS :: Monad m => MSF (WriterT s m) a b -> MSF m a (s, b)
+ Control.Monad.Trans.MSF.Writer: runWriterS' :: (Monoid s, Functor m, Monad m) => MSF (WriterT s m) a b -> MSF m a (s, b)
+ Control.Monad.Trans.MSF.Writer: runWriterS'' :: (Monoid s, Functor m, Monad m) => MSF (WriterT s m) a b -> MSF m a (s, b)
+ Control.Monad.Trans.MSF.Writer: unwrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)
+ Control.Monad.Trans.MSF.Writer: wrapMSFWriterT :: (Monoid s, Monad m) => (a -> m ((s, b), ct)) -> a -> WriterT s m (b, ct)
+ Control.Monad.Trans.MSF.Writer: writerS :: (Monad m, Monoid s) => MSF m a (s, b) -> MSF (WriterT s m) a b
+ Control.Monad.Trans.MSF.Writer: writerS' :: (Monad m, Monoid s) => MSF m a (s, b) -> MSF (WriterT s m) a b
+ Control.Monad.Trans.MSF.Writer: writerS'' :: (Monad m, Monoid w) => MSF m a (w, b) -> MSF (WriterT w 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.Core: MSF :: (a -> m (b, MSF m a b)) -> MSF m a b
+ Data.MonadicStreamFunction.Core: [unMSF] :: MSF m a b -> a -> m (b, MSF m a b)
+ Data.MonadicStreamFunction.Core: arrM :: Monad m => (a -> m b) -> MSF m a b
+ Data.MonadicStreamFunction.Core: data MSF m a b
+ Data.MonadicStreamFunction.Core: instance (GHC.Base.Functor m, GHC.Base.Monad m) => GHC.Base.Applicative (Data.MonadicStreamFunction.Core.MSF m a)
+ Data.MonadicStreamFunction.Core: instance GHC.Base.Functor m => GHC.Base.Functor (Data.MonadicStreamFunction.Core.MSF m a)
+ Data.MonadicStreamFunction.Core: instance GHC.Base.Monad m => Control.Arrow.Arrow (Data.MonadicStreamFunction.Core.MSF m)
+ Data.MonadicStreamFunction.Core: instance GHC.Base.Monad m => Control.Category.Category (Data.MonadicStreamFunction.Core.MSF m)
+ Data.MonadicStreamFunction.Core: liftMSFBase :: (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b
+ Data.MonadicStreamFunction.Core: liftMSFPurer :: (Monad m2, Monad m1) => (forall c. m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b
+ Data.MonadicStreamFunction.Core: liftMSFTrans :: (MonadTrans t, Monad m, Monad (t m)) => MSF m a b -> MSF (t m) a b
+ Data.MonadicStreamFunction.Core: liftS :: (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b
+ Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Float.Floating b) => GHC.Float.Floating (Data.MonadicStreamFunction.Core.MSF m a b)
+ Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Num.Num b) => GHC.Num.Num (Data.MonadicStreamFunction.Core.MSF m a b)
+ Data.MonadicStreamFunction.Instances.Num: instance (GHC.Base.Monad m, GHC.Real.Fractional b) => GHC.Real.Fractional (Data.MonadicStreamFunction.Core.MSF m a b)
+ Data.MonadicStreamFunction.Instances.VectorSpace: instance (GHC.Base.Monad m, Data.VectorSpace.RModule v) => Data.VectorSpace.RModule (Data.MonadicStreamFunction.Core.MSF m a v)
+ Data.MonadicStreamFunction.Instances.VectorSpace: instance (GHC.Base.Monad m, Data.VectorSpace.VectorSpace v) => Data.VectorSpace.VectorSpace (Data.MonadicStreamFunction.Core.MSF m a v)
+ Data.MonadicStreamFunction.ReactHandle: createWormhole :: MonadIO m => a -> m (MSF m a (), MSF m () a)
+ Data.MonadicStreamFunction.ReactHandle: react :: MonadIO m => ReactHandle m -> m ()
+ Data.MonadicStreamFunction.ReactHandle: reactInit :: MonadIO m => MSF m () () -> m (ReactHandle m)
+ Data.MonadicStreamFunction.ReactHandle: type ReactHandle m = IORef (MSF m () ())
+ Data.MonadicStreamFunction.Util: (>>>^) :: MonadBase m1 m2 => MSF m2 a b -> MSF m1 b c -> MSF m2 a c
+ Data.MonadicStreamFunction.Util: (^>>>) :: MonadBase m1 m2 => MSF m1 a b -> MSF m2 b c -> MSF m2 a c
+ Data.MonadicStreamFunction.Util: accumulateWith :: Monad m => (a -> s -> s) -> s -> MSF m a s
+ Data.MonadicStreamFunction.Util: arrM_ :: Monad m => m b -> MSF m a b
+ Data.MonadicStreamFunction.Util: count :: (Num n, Monad m) => MSF m a n
+ Data.MonadicStreamFunction.Util: embed_ :: (Functor m, Monad m) => MSF m a () -> [a] -> m ()
+ Data.MonadicStreamFunction.Util: iPost :: Monad m => b -> MSF m a b -> MSF m a b
+ Data.MonadicStreamFunction.Util: insert :: Monad m => MSF m (m a) a
+ Data.MonadicStreamFunction.Util: mapMSF :: Monad m => MSF m a b -> MSF m [a] [b]
+ Data.MonadicStreamFunction.Util: mapMaybeS :: Monad m => MSF m a b -> MSF m (Maybe a) (Maybe b)
+ Data.MonadicStreamFunction.Util: mappendFrom :: (Monoid n, Monad m) => n -> MSF m n n
+ Data.MonadicStreamFunction.Util: mappendS :: (Monoid n, Monad m) => MSF m n n
+ Data.MonadicStreamFunction.Util: next :: Monad m => b -> MSF m a b -> MSF m a b
+ Data.MonadicStreamFunction.Util: pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a
+ Data.MonadicStreamFunction.Util: repeatedly :: Monad m => (a -> a) -> a -> MSF m () a
+ Data.MonadicStreamFunction.Util: sumFrom :: (RModule v, Monad m) => v -> MSF m v v
+ Data.MonadicStreamFunction.Util: sumS :: (RModule v, Monad m) => MSF m v v
+ Data.MonadicStreamFunction.Util: trace :: Show a => String -> MSF IO a a
+ Data.MonadicStreamFunction.Util: traceWhen :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MSF m a a
+ Data.MonadicStreamFunction.Util: traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a
+ Data.MonadicStreamFunction.Util: type MSink m a = MSF m a ()
+ Data.MonadicStreamFunction.Util: type MStream m a = MSF m () a
+ Data.MonadicStreamFunction.Util: unfold :: Monad m => (a -> (b, a)) -> a -> MSF m () b
+ Data.MonadicStreamFunction.Util: withSideEffect :: Monad m => (a -> m b) -> MSF m a a
+ Data.MonadicStreamFunction.Util: withSideEffect_ :: Monad m => m b -> MSF m a a
+ Data.VectorSpace.Fractional: instance GHC.Num.Num a => Data.VectorSpace.InnerProductSpace a
+ Data.VectorSpace.Fractional: instance GHC.Num.Num a => Data.VectorSpace.RModule a
+ Data.VectorSpace.Fractional: instance GHC.Real.Fractional a => Data.VectorSpace.VectorSpace a
- Data.MonadicStreamFunction.Core: delay :: Monad m => a -> MStreamF m a a
+ Data.MonadicStreamFunction.Core: delay :: Monad m => a -> MSF m a a
- Data.MonadicStreamFunction.Core: embed :: Monad m => MStreamF m a b -> [a] -> m [b]
+ Data.MonadicStreamFunction.Core: embed :: Monad m => MSF m a b -> [a] -> m [b]
- Data.MonadicStreamFunction.Core: feedback :: Monad m => c -> MStreamF m (a, c) (b, c) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: feedback :: Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b
- Data.MonadicStreamFunction.Core: iPre :: Monad m => a -> MStreamF m a a
+ Data.MonadicStreamFunction.Core: iPre :: Monad m => a -> MSF m a a
- Data.MonadicStreamFunction.Core: performOnFirstSample :: Monad m => m (MStreamF m a b) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: performOnFirstSample :: Monad m => m (MSF m a b) -> MSF m a b
- Data.MonadicStreamFunction.Core: reactimate :: Monad m => MStreamF m () () -> m ()
+ Data.MonadicStreamFunction.Core: reactimate :: Monad m => MSF m () () -> m ()
- Data.MonadicStreamFunction.Core: reactimateB :: Monad m => MStreamF m () Bool -> m ()
+ Data.MonadicStreamFunction.Core: reactimateB :: Monad m => MSF m () Bool -> m ()
- Data.MonadicStreamFunction.Core: switch :: Monad m => MStreamF m a (b, Maybe c) -> (c -> MStreamF m a b) -> MStreamF m a b
+ Data.MonadicStreamFunction.Core: switch :: Monad m => MSF m a (b, Maybe c) -> (c -> MSF m a b) -> MSF m a b
- Data.MonadicStreamFunction.Instances: elementwise :: Monad m => (b -> c) -> MStreamF m a b -> MStreamF m a c
+ 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) -> MStreamF m a b -> MStreamF m a c -> MStreamF m a d
+ Data.MonadicStreamFunction.Instances: elementwise2 :: Monad m => (b -> c -> d) -> MSF m a b -> MSF m a c -> MSF m a d
- Data.MonadicStreamFunction.Parallel: (&|&) :: Monad m => MStreamF m a b -> MStreamF m a c -> MStreamF m a (b, c)
+ Data.MonadicStreamFunction.Parallel: (&|&) :: Monad m => MSF m a b -> MSF m a c -> MSF m a (b, c)
- Data.MonadicStreamFunction.Parallel: (*|*) :: Monad m => MStreamF m a b -> MStreamF m c d -> MStreamF m (a, c) (b, d)
+ Data.MonadicStreamFunction.Parallel: (*|*) :: Monad m => MSF m a b -> MSF m c d -> MSF m (a, c) (b, d)

Files

dunai.cabal view
@@ -1,7 +1,35 @@ name:                dunai-version:             0.1.0.0+version:             0.1.1.0 synopsis:            Generalised reactive framework supporting classic, arrowized and monadic FRP.--- description:+description:+  Dunai is DSL for strongly-typed CPS-based composable transformations.+  .+  Dunai is based on a concept of Monadic Stream Functions (MSFs). MSFs are+  transformations defined by a function @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@+  that executes one step of a simulation, and produces an output in a monadic+  context, and a continuation to be used for future steps.+  .+  MSFs are a generalisation of the implementation mechanism used by Yampa,+  Wormholes and other FRP and reactive implementations.+  .+  When combined with different monads, they produce interesting effects. For+  example, when combined with the @Maybe@ monad, they become transformations+  that may stop producing outputs (and continuations). The @Either@ monad gives+  rise to MSFs that end with a result (akin to Tasks in Yampa, and Monadic+  FRP).+  .+  Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a b@+  for a specific transformer @t@ often gives rise to known FRP constructs. For+  instance, flattening with @EitherT@ gives rise to switching, and flattening+  with @ListT@ gives rise to parallelism with broadcasting.+  .+  MSFs can be used to implement many FRP variants, including Arrowized FRP,+  Classic FRP, and plain reactive programming. Arrowized and applicative+  syntax are both supported.+  .+  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>). license:             BSD3 license-file:        LICENSE author:              Ivan Perez, Manuel Bärenz@@ -23,7 +51,13 @@   manual: True  library-  exposed-modules:   Control.Monad.Trans.MStreamF+  exposed-modules:   Control.Monad.Trans.MSF+                     Control.Monad.Trans.MSF.Except+                     Control.Monad.Trans.MSF.GenLift+                     Control.Monad.Trans.MSF.Maybe+                     Control.Monad.Trans.MSF.Reader+                     Control.Monad.Trans.MSF.State+                     Control.Monad.Trans.MSF.Writer                      Data.MonadicStreamFunction                      Data.MonadicStreamFunction.Core                      Data.MonadicStreamFunction.ArrowChoice@@ -33,10 +67,12 @@                      Data.MonadicStreamFunction.Instances.Num                      Data.MonadicStreamFunction.Instances.VectorSpace                      Data.MonadicStreamFunction.Parallel+                     Data.MonadicStreamFunction.ReactHandle+                     Data.MonadicStreamFunction.Util -		     -- Auxiliary definitions+                     -- Auxiliary definitions                      Data.VectorSpace-                     Data.VectorSpace.Instances+                     Data.VectorSpace.Fractional                      Data.VectorSpace.Tuples                      Data.VectorSpace.Specific @@ -80,4 +116,4 @@  source-repository head   type:     git-  location: git@bitbucket.org:iperezdominguez/dunai.git+  location: git@github.com:ivanperez-keera/dunai.git
src/Control/Arrow/Util.hs view
@@ -1,10 +1,6 @@ module Control.Arrow.Util where --- Do we even need that module? How much of it exists in the standard library?- import Control.Arrow-import Control.Category (id)-import Prelude hiding (id)  -- Hah! I shall implement this for TimelessSFs and SFs at the same time! constantly :: Arrow a => b -> a c b@@ -22,9 +18,11 @@ (>->) = (>>>) {-# INLINE (>->) #-} +-- import Control.Category (id)+-- import Prelude hiding (id) -(&&&!) :: Arrow a => a b c -> a b () -> a b c-a1 &&&! a2 = (a1 &&& a2) >>> arr fst+-- (&&&!) :: Arrow a => a b c -> a b () -> a b c+-- a1 &&&! a2 = (a1 &&& a2) >>> arr fst -sink :: Arrow a => a b c -> a c () -> a b c-a1 `sink` a2 = a1 >>> (id &&& a2) >>> arr fst+-- sink :: Arrow a => a b c -> a c () -> a b c+-- a1 `sink` a2 = a1 >>> (id &&& a2) >>> arr fst
+ src/Control/Monad/Trans/MSF.hs view
@@ -0,0 +1,12 @@+{-# LANGUAGE Rank2Types          #-}++module Control.Monad.Trans.MSF ( module X ) where+-- Caution, RWS is not exported since names collide with Reader, State and Writer++import Control.Monad.Trans.MSF.GenLift as X++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
+ src/Control/Monad/Trans/MSF/Except.hs view
@@ -0,0 +1,147 @@+{-# LANGUAGE Arrows              #-}+{-# LANGUAGE Rank2Types          #-}+module Control.Monad.Trans.MSF.Except+  ( module Control.Monad.Trans.MSF.Except+  , module Control.Monad.Trans.Except+  ) 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++-- Internal+import Control.Monad.Trans.MSF.GenLift+import Data.MonadicStreamFunction+++-- * Throwing exceptions++throwOnCond :: Monad m => (a -> Bool) -> e -> MSF (ExceptT e m) a a+throwOnCond cond e = proc a -> if cond a+    then arrM throwE -< e+    else returnA -< a++throwOnCondM :: Monad m => (a -> m Bool) -> e -> MSF (ExceptT e m) a a+throwOnCondM cond e = proc a -> do+    b <- arrM (lift . cond) -< a+    if b+    then arrM throwE -< e+    else returnA -< a+++throwOn :: Monad m => e -> MSF (ExceptT e m) Bool ()+throwOn e = proc b -> throwOn' -< (b, e)++throwOn' :: Monad m => MSF (ExceptT e m) (Bool, e) ()+throwOn' = proc (b, e) -> if b+    then arrM throwE -< e+    else returnA -< ()++throwMaybe :: Monad m => MSF (ExceptT e m) (Maybe e) (Maybe a)+throwMaybe = mapMaybeS $ arrM throwE++throwS :: Monad m => MSF (ExceptT e m) e a+throwS = arrM throwE++throw :: Monad m => e -> MSF (ExceptT e m) a b+throw = arrM_ . throwE++pass :: Monad m => MSF (ExceptT e m) a a+pass = Category.id++-- * Catching exceptions++{-+catchS' :: Monad m => MSF (ExceptT e m) a b -> (e -> m (b, MSF m a b)) -> MSF m a b+catchS' msf f = MSF $ \a -> (unMSF msf a) f `catchFinal` f+-}+catchS :: Monad m => MSF (ExceptT e m) a b -> (e -> MSF m a b) -> MSF m a b+catchS msf f = MSF $ \a -> do+    cont <- runExceptT $ unMSF msf a+    case cont of+        Left e          -> unMSF (f e) a+        Right (b, msf') -> return (b, msf' `catchS` f)++-- catchFinal :: Monad m => ExceptT e m a -> (e -> m a) -> m a+-- catchFinal action f = do+--     ea <- runExceptT action+--     case ea of+--         Left  e -> f e+--         Right a -> return a++-- Similar to delayed switching. Looses a b in case of exception+untilE :: Monad m => MSF m a b -> MSF m b (Maybe e)+       -> MSF (ExceptT e m) a b+untilE msf msfe = proc a -> do+    b <- liftMSFTrans msf -< a+    me <- liftMSFTrans msfe -< b+    inExceptT -< (ExceptT . return) (maybe (Right b) Left me)++exceptS :: Monad m => MSF (ExceptT e m) a b -> MSF m a (Either e b)+exceptS msf = go+ where+   go = MSF $ \a -> do+          cont <- runExceptT $ unMSF msf a+          case cont of+            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++{-+tagged :: MSF (ExceptT e m) a b -> MSF (ExceptT t m) (a, t) b+tagged msf = MSF $ \(a, t) -> ExceptT $ do+  cont <- runExceptT $ unMSF msf a+  case cont of+    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 }++try :: MSF (ExceptT e m) a b -> MSFExcept m a b e+try = MSFExcept++instance Functor (MSFExcept m a b) where++instance Monad m => Applicative (MSFExcept m a b) where+  pure = MSFExcept . throw++instance Monad m => Monad (MSFExcept m a b) where+  MSFExcept msf >>= f = MSFExcept $ MSF $ \a -> do+    cont <- lift $ runExceptT $ unMSF msf a+    case cont of+      Left e          -> unMSF (runMSFExcept $ f e) a+      Right (b, msf') -> return (b, runMSFExcept $ try msf' >>= f)++data Empty++safely :: Monad m => MSFExcept m a b Empty -> MSF m a b+safely (MSFExcept msf) = safely' msf+  where+    safely' msf = MSF $ \a -> do+      Right (b, msf') <- runExceptT $ unMSF msf a+      return (b, safely' msf')++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 => m b -> MSFExcept m c d ()+once_ = once . const++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+    Right (b, msf') -> return $ Right (b, tagged msf')
+ src/Control/Monad/Trans/MSF/GenLift.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE Rank2Types          #-}+module Control.Monad.Trans.MSF.GenLift where++import Control.Applicative+import Data.MonadicStreamFunction++-- * Attempt at writing a more generic MSF lifting combinator.  This is+-- here only to make it easier to find, in a perfect world we'd move+-- this to a different module/branch, or at least to the bottom of the+-- file.+--+-- TODO: does this also work well with the state and the writer monads?+--+-- Even if this code works, it's difficult to understand the concept.+--+-- It is also unclear how much it helps. Ideally, the auxiliary function+-- should operate only on monadic values, not monadic stream functions.+-- That way we could separate concepts: namely the recursion pattern+-- from the monadic lifting/unlifting/sequencing.+--+-- Maybe if we split f in several functions, one that does some sort of+-- a -> a1 transformation, another that does some b1 -> b+-- transformation, with the monads and continuations somewhere, it'll+-- make more sense.+--+-- Based on this lifting function we can also defined all the other+-- liftings we have in Core:+--+-- liftMSFPurer' :: (Monad m1, Monad m)+--                    => (m1 (b, MSF m1 a b) -> m (b, MSF m1 a b))+--                    -> MSF m1 a b+--                    -> MSF m  a b+-- liftMSFPurer' f = lifterS (\g a -> f $ g a)+--+-- More liftings:+-- liftMSFTrans = liftMSFPurer lift+-- liftMSFBase  = liftMSFPurer liftBase+--+-- And a strict version of liftMSFPurer:+-- liftMStreamPurer' f = liftMSFPurer (f >=> whnfVal)+--   where whnfVal p@(b,_) = b `seq` return p+--+-- MB: I'm not sure we're gaining much insight by rewriting all the lifting+-- functions like that.+-- IP: I said the same thing above ("It is also unclear how much it+-- helps."). It's work in progress.+--+-- MB: The type (a1 -> m1 (b1, MSF m1 a1 b1)) is just MSF m1 a1 b1.+-- IP: I'm looking for a lifting pattern in terms of m m1 a b a1 and b1. By+-- exposing the function, I'm hoping to *eventually see* the pattern. If I hide+-- it in the MSF, then it'll always remain hidden.+lifterS :: (Monad m, Monad m1)+        => ((a1 -> m1 (b1, MSF m1 a1 b1)) -> a -> m (b, MSF m1 a1 b1))+        -> MSF m1 a1 b1+        -> MSF m  a  b+lifterS f msf = MSF $ \a -> do+  (b, msf') <- f (unMSF msf) a+  return (b, lifterS f msf')++-- ** Another wrapper idea+transS :: (Monad m1, Monad m2)+       => (a2 -> m1 a1)+       -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c))+       -> MSF m1 a1 b1 -> MSF m2 a2 b2+transS transformInput transformOutput msf = MSF $ \a2 -> do+    (b2, msf') <- transformOutput a2 $ unMSF msf =<< transformInput a2+    return (b2, transS transformInput transformOutput msf')++-- ** A more general lifting mechanism that enables recovery.+transG1 :: (Monad m1, Functor m2, Monad m2)+        => (a2 -> m1 a1)+        -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c))+        -> MSF m1 a1 b1 -> MSF m2 a2 b2+transG1 transformInput transformOutput msf =+  transG transformInput transformOutput' msf+    where+      -- transformOutput' :: forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c)+      transformOutput' a b = second Just <$> transformOutput a b++transG :: (Monad m1, Monad m2)+       => (a2 -> m1 a1)+       -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c))+       -> MSF m1 a1 b1 -> MSF m2 a2 b2+transG transformInput transformOutput msf = go+  where go = MSF $ \a2 -> do+               (b2, msf') <- transformOutput a2 $ unMSF msf =<< transformInput a2+               case msf' of+                 Just msf'' -> return (b2, transG transformInput transformOutput msf'')+                 Nothing    -> return (b2, go)++-- transGN :: (Monad m1, Monad m2)+--         => (a2 -> m1 a1)+--         -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, [c]))+--         -> MSF m1 a1 b1 -> MSF m2 a2 b2+-- transGN transformInput transformOutput msf = go+--   where go = MSF $ \a2 -> do+--                (b2, msf') <- transformOutput a2 $ unMSF msf =<< transformInput a2+--                case msf' of+--                  []      -> return (b2, go)+--                  [msf''] -> return (b2, transGN transformInput transformOutput msf'')+--                  ms      ->++-- ** Wrapping/unwrapping+--+-- IP: Alternative formulation (typechecks just fine):+--+-- FIXME: The foralls may get in the way. They may not be necessary.  MB+-- raised the issue already for similar code in Core.+--+type Wrapper   m1 m2 t1 t2 = forall a b . (t1 a -> m2 b     ) -> (a    -> m1 (t2 b))+type Unwrapper m1 m2 t1 t2 = forall a b . (a    -> m1 (t2 b)) -> (t1 a -> m2 b     )+--+-- Helper type, for when we need some identity * -> * type constructor that+-- does not get in the way.+--+type Id a = a
+ src/Control/Monad/Trans/MSF/Maybe.hs view
@@ -0,0 +1,117 @@+{-# LANGUAGE Arrows              #-}+{-# LANGUAGE Rank2Types          #-}+module Control.Monad.Trans.MSF.Maybe+  ( module Control.Monad.Trans.MSF.Maybe+  , module Control.Monad.Trans.Maybe+  ) where++-- External+import Control.Monad.Trans.Maybe+  hiding (liftCallCC, liftCatch, liftListen, liftPass) -- Avoid conflicting exports++-- Internal+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+    transformInput       = return+    transformOutput _ m1 = do r <- runMaybeT m1+                              case r of+                                Nothing     -> return (Nothing, Nothing)+                                Just (b, c) -> return (Just b,  Just c)+++-- * Throwing Nothing as an exception ("exiting")++exit :: Monad m => MSF (MaybeT m) a b+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)++exitIf :: Monad m => MSF (MaybeT m) Bool ()+exitIf = MSF $ \b -> MaybeT $ return $ if b then Nothing else Just ((), exitIf)++-- Just a is passed along, Nothing causes the whole MSF to exit+maybeExit :: Monad m => MSF (MaybeT m) (Maybe a) a+maybeExit = MSF $ MaybeT . return . fmap (\x -> (x, maybeExit))++inMaybeT :: Monad m => MSF (MaybeT m) (Maybe a) a+inMaybeT = arrM $ MaybeT . return++-- * Catching Maybe exceptions++untilMaybe :: Monad m => MSF m a b -> MSF m b Bool -> MSF (MaybeT m) a b+untilMaybe msf cond = proc a -> do+  b <- liftMSFTrans msf -< a+  c <- liftMSFTrans cond -< b+  inMaybeT -< if c then Nothing else Just b++catchMaybe :: Monad m => MSF (MaybeT m) a b -> MSF m a b -> MSF m a b+catchMaybe msf1 msf2 = MSF $ \a -> do+  cont <- runMaybeT $ unMSF msf1 a+  case cont of+    Just (b, msf1') -> return (b, msf1' `catchMaybe` msf2)+    Nothing         -> unMSF msf2 a+++++-- * Running MaybeT+runMaybeS :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)+runMaybeS msf = go+  where+    go = MSF $ \a -> do+           bmsf <- runMaybeT $ unMSF msf a+           case bmsf of+             Just (b, msf') -> return (Just b, runMaybeS msf')+             Nothing        -> return (Nothing, go)+++-- mapMaybeS msf == runMaybeS (inMaybeT >>> lift mapMaybeS)++{-+maybeS :: Monad m => MSF m a (Maybe b) -> MSF (MaybeT m) a b+maybeS msf = MSF $ \a -> MaybeT $ return $ unMSF msf a+-- maybeS msf == lift msf >>> inMaybeT+-}++{-+-- MB: Doesn't typecheck, I don't know why+--+-- IP: Because of the forall in runTS.+--+-- From the action runMaybeT msfaction it does not know that+-- the second element of the pair in 'thing' will be a continuation.+--+-- The first branch of the case works because you are passing the+-- msf' as is.+--+-- In the second one, you are passing msf, which has the specific type+-- MSF (MaybeT m) a b.+--+-- Two things you can try (to help you see that this is indeed why GHC is+-- complaining):+--   - Make the second continuation undefined. Then it typechecks.+--   - Use ScopedTypeVariables and a let binding to type msf' in the+--   first branch of the case selector. It'll complain about the type+--   of msf' if you say it's forcibly a MSF (MaybeT m) a b.+--++runMaybeS'' :: Monad m => MSF (MaybeT m) a b -> MSF m a (Maybe b)+runMaybeS'' msf = transS transformInput transformOutput msf+  where+    transformInput  = return+    transformOutput _ msfaction = do+      thing <- runMaybeT msfaction+      case thing of+        Just (b, msf') -> return (Just b, msf')+        Nothing        -> return (Nothing, msf)+-}
+ src/Control/Monad/Trans/MSF/Reader.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE Rank2Types          #-}+module Control.Monad.Trans.MSF.Reader+  ( module Control.Monad.Trans.MSF.Reader+  , module Control.Monad.Trans.Reader+  ) where++-- External+import Control.Monad.Trans.Reader+  hiding (liftCallCC, liftCatch) -- Avoid conflicting exports+++-- Internal+import Control.Monad.Trans.MSF.GenLift+import Data.MonadicStreamFunction+++-- * Reader monad+readerS :: Monad m => MSF m (s, a) b -> MSF (ReaderT s m) a b+readerS msf = MSF $ \a -> do+  (b, msf') <- ReaderT $ \s -> unMSF msf (s, a)+  return (b, readerS msf')++runReaderS :: Monad m => MSF (ReaderT s m) a b -> MSF m (s, a) b+runReaderS msf = MSF $ \(s,a) -> do+  (b, msf') <- runReaderT (unMSF msf a) s+  return (b, runReaderS msf')++-- ** Alternative wrapping/unwrapping MSF combinators using generic lifting++runReaderS' :: Monad m => MSF (ReaderT s m) a b -> MSF m (s, a) b+runReaderS' = lifterS unwrapReaderT+++type ReaderWrapper   s m = Wrapper   (ReaderT s m) m ((,) s) Id+type ReaderUnwrapper s m = Unwrapper (ReaderT s m) m ((,) s) Id+-- and use the types:+-- wrapReaderT   :: ReaderWrapper s m+-- unwrapReaderT :: ReaderUnwrapper s m++wrapReaderT :: ((s, a) -> m b) -> a -> ReaderT s m b+wrapReaderT g i = ReaderT $ g . flip (,) i++unwrapReaderT :: (a -> ReaderT s m b) -> (s, a) -> m b+unwrapReaderT g i = uncurry (flip runReaderT) $ second g i++readerS' :: Monad m => MSF m (s, a) b -> MSF (ReaderT s m) a b+readerS' = lifterS wrapReaderT++runReaderS'' :: Monad m => MSF (ReaderT s m) a b -> MSF m (s, a) b+runReaderS'' = transG transformInput transformOutput+  where+    transformInput  (_, a) = return a+    transformOutput (s, _) m1 = do (r, c) <- runReaderT m1 s+                                   return (r, Just c)++{-+readerS'' :: Monad m => MSF m (s, a) b -> MSF (ReaderT s m) a b+readerS'' = transS transformInput transformOutput+  where+    transformInput :: a -> m (s, a)+    transformInput a = (,) <$> asks <*> pure a+    transformOutput _ = lift+-}++-- ** Auxiliary functions related to ReaderT++-- IP: Is runReaderS_ msf s = arr (\a -> (s,a)) >>> runReaderS msf ?+-- MB: Yes, but possibly more efficient.+runReaderS_ :: Monad m => MSF (ReaderT s m) a b -> s -> MSF m a b+runReaderS_ msf s = MSF $ \a -> do+  (b, msf') <- runReaderT (unMSF msf a) s+  return (b, runReaderS_ msf' s)
+ src/Control/Monad/Trans/MSF/State.hs view
@@ -0,0 +1,82 @@+{-# LANGUAGE Rank2Types          #-}+module Control.Monad.Trans.MSF.State+  ( module Control.Monad.Trans.MSF.State+  , module Control.Monad.Trans.State.Strict+  ) where++-- External+import Control.Applicative+import Control.Monad.Trans.State.Strict+  hiding (liftCallCC, liftCatch, liftListen, liftPass) -- Avoid conflicting exports++-- Internal+import Control.Monad.Trans.MSF.GenLift+import Data.MonadicStreamFunction++++-- * Running and wrapping+stateS :: Monad m => MSF m (s, a) (s, b) -> MSF (StateT s m) a b+stateS msf = MSF $ \a -> StateT $ \s -> do+    ((s', b), msf') <- unMSF msf (s, a)+    return ((b, stateS msf'), s')++runStateS :: Monad m => MSF (StateT s m) a b -> MSF m (s, a) (s, b)+runStateS msf = MSF $ \(s, a) -> do+    ((b, msf'), s') <- runStateT (unMSF msf a) s+    return ((s', b), runStateS msf')++-- * Auxiliary functions++-- IP: Is runStateS_ msf s = feedback s $ runStateS msf >>> arr (\(s,b) -> ((s,b), s)) ?+runStateS_ :: Monad m => MSF (StateT s m) a b -> s -> MSF m a (s, b)+runStateS_ msf s = MSF $ \a -> do+    ((b, msf'), s') <- runStateT (unMSF msf a) s+    return ((s', b), runStateS_ msf' s')++-- IP: Is runStateS__ msf s = feedback s $ runStateS msf >>> arr (\(s,b) -> (b, s)) ?+runStateS__ :: Monad m => MSF (StateT s m) a b -> s -> MSF m a b+runStateS__ msf s = MSF $ \a -> do+    ((b, msf'), s') <- runStateT (unMSF msf a) s+    return (b, runStateS__ msf' s')+++runStateS''' :: (Functor m, Monad m) => MSF (StateT s m) a b -> MSF m (s, a) (s, b)+runStateS''' = transG transformInput transformOutput+  where+    transformInput  (_, a)           = return a+    transformOutput (s, _) msfaction = sym <$> runStateT msfaction s+    sym ((b, msf), s)                = ((s, b), Just msf)++-- * Alternative running/wrapping MSF combinators using generic lifting+--+-- IPerez: TODO: Is this exactly the same as stateS?+stateS' :: (Functor m, Monad m) => MSF m (s, a) (s, b) -> MSF (StateT s m) a b+stateS' = lifterS (\g i -> StateT ((resort <$>) . g . flip (,) i))+ where resort ((s, b), ct) = ((b, ct), s)++-- stateS' :: Monad m => MSF m (s, a) (s, b) -> MSF (StateT s m) a b+-- stateS' = lifterS $ \f a -> StateT $ \s -> do+--   ((s', b), msf') <- f (s, a)+--   return ((b, msf'), s')++runStateS' :: (Functor m, Monad m) => MSF (StateT s m) a b -> MSF m (s, a) (s, b)+runStateS' = lifterS (\g i -> resort <$> uncurry (flip runStateT) (second g i))+ where resort ((b, msf), s) = ((s, b), msf)+++runStateS'' :: (Functor m, Monad m) => MSF (StateT s m) a b -> MSF m (s, a) (s, b)+runStateS'' = transS transformInput transformOutput+  where+    transformInput  (_, a)           = return a+    transformOutput (s, _) msfaction = sym <$> runStateT msfaction s+    sym ((b, msf), s)                = ((s, b), msf)++{-+stateS'' :: Monad m => MSF m (s, a) (s, b) -> MSF (StateT s m) a b+stateS'' = transS transformInput transformOutput+  where+    transformInput  (_, a) = return a+    transformOutput (s, _) = do+        put s+-}
+ src/Control/Monad/Trans/MSF/Writer.hs view
@@ -0,0 +1,71 @@+module Control.Monad.Trans.MSF.Writer+  ( module Control.Monad.Trans.MSF.Writer+  , module Control.Monad.Trans.Writer.Strict+  ) where++-- External+import Control.Applicative+import Control.Monad.Trans.Class+import Control.Monad.Trans.Writer.Strict+  hiding (liftCallCC, liftCatch, pass) -- Avoid conflicting exports+import Data.Monoid++-- Internal+import Control.Monad.Trans.MSF.GenLift+import Data.MonadicStreamFunction++-- * Writer monad+writerS :: (Monad m, Monoid s) => MSF m a (s, b) -> MSF (WriterT s m) a b+writerS msf = MSF $ \a -> do+    ((s, b), msf') <- lift $ unMSF msf a+    tell s+    return (b, writerS msf')++runWriterS :: Monad m => MSF (WriterT s m) a b -> MSF m a (s, b)+runWriterS msf = MSF $ \a -> do+    ((b, msf'), s') <- runWriterT $ unMSF msf a+    return ((s', b), runWriterS msf')+++-- * Alternative running/wrapping MSF combinators using generic lifting++writerS' :: (Monad m, Monoid s) => MSF m a (s, b) -> MSF (WriterT s m) a b+writerS' = lifterS wrapMSFWriterT++runWriterS' :: (Monoid s, Functor m, Monad m) => MSF (WriterT s m) a b -> MSF m a (s, b)+runWriterS' = lifterS unwrapMSFWriterT++writerS'' :: (Monad m, Monoid w) => MSF m a (w, b) -> MSF (WriterT w m) a b+writerS'' = transS transformInput transformOutput+  where+    transformInput = return+    transformOutput _ msfaction = do+        ((w, b), msf') <- lift msfaction+        tell w+        return (b, msf')++runWriterS'' :: (Monoid s, Functor m, Monad m) => MSF (WriterT s m) a b -> MSF m a (s, b)+runWriterS'' = transS transformInput transformOutput+  where+    transformInput              = return+    transformOutput _ msfaction = sym <$> runWriterT msfaction+    sym ((b, msf), s)           = ((s, b), msf)++-- ** Wrapping/unwrapping functions+--+-- TODO: These are *almost*-MSF-agnostic wrapping/unwrapping functions.+-- The continuations (and therefore the stream functions) are still+-- there, but now we know nothing about them, not even their type.+-- Monadic actions carry an extra value, of some polymorphic type ct,+-- which is only necessary to extract the output and the context.+--+-- wrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)+wrapMSFWriterT :: (Monoid s, Monad m) => (a -> m ((s, b), ct)) -> a -> WriterT s m (b, ct)+wrapMSFWriterT g i = do+  ((s, b), msf) <- lift $ g i+  tell s+  return (b, msf)++unwrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)+unwrapMSFWriterT g i = resort <$> runWriterT (g i)+  where resort ((b, msf), s) = ((s, b), msf)
− src/Control/Monad/Trans/MStreamF.hs
@@ -1,509 +0,0 @@-{-# LANGUAGE Arrows              #-}-{-# LANGUAGE Rank2Types          #-}--module Control.Monad.Trans.MStreamF where--import Data.Monoid-import Control.Applicative-import Control.Arrow-import Control.Monad.Trans.Class-import Control.Monad.Trans.Except-import Control.Monad.Trans.List-import Control.Monad.Trans.Maybe-import Control.Monad.Trans.State.Strict-import Control.Monad.Trans.Reader-import Control.Monad.Trans.RWS.Strict hiding (tell, asks, put)-import Control.Monad.Trans.Writer.Strict--import Data.MonadicStreamFunction---- * Attempt at writing a more generic MSF lifting combinator.  This is--- here only to make it easier to find, in a perfect world we'd move--- this to a different module/branch, or at least to the bottom of the--- file.------ TODO: does this also work well with the state and the writer monads?------ Even if this code works, it's difficult to understand the concept.------ It is also unclear how much it helps. Ideally, the auxiliary function--- should operate only on monadic values, not monadic stream functions.--- That way we could separate concepts: namely the recursion pattern--- from the monadic lifting/unlifting/sequencing.------ Maybe if we split f in several functions, one that does some sort of--- a -> a1 transformation, another that does some b1 -> b--- transformation, with the monads and continuations somewhere, it'll--- make more sense.------ Based on this lifting function we can also defined all the other--- liftings we have in Core:------ liftMStreamFPurer' :: (Monad m1, Monad m)---                    => (m1 (b, MStreamF m1 a b) -> m (b, MStreamF m1 a b))---                    -> MStreamF m1 a b---                    -> MStreamF m  a b--- liftMStreamFPurer' f = lifterS (\g a -> f $ g a)------ More liftings:--- liftMStreamFTrans = liftMStreamFPurer lift--- liftMStreamFBase  = liftMStreamFPurer liftBase------ And a strict version of liftMStreamFPurer:--- liftMStreamPurer' f = liftMStreamFPurer (f >=> whnfVal)---   where whnfVal p@(b,_) = b `seq` return p------ MB: I'm not sure we're gaining much insight by rewriting all the lifting--- functions like that.--- IP: I said the same thing above ("It is also unclear how much it--- helps."). It's work in progress.------ MB: The type (a1 -> m1 (b1, MStreamF m1 a1 b1)) is just MStreamF m1 a1 b1.--- IP: I'm looking for a lifting pattern in terms of m m1 a b a1 and b1. By--- exposing the function, I'm hoping to *eventually see* the pattern. If I hide--- it in the MStreamF, then it'll always remain hidden.-lifterS :: (Monad m, Monad m1)-        => ((a1 -> m1 (b1, MStreamF m1 a1 b1)) -> a -> m (b, MStreamF m1 a1 b1))-        -> MStreamF m1 a1 b1-        -> MStreamF m  a  b-lifterS f msf = MStreamF $ \a -> do-  (b, msf') <- f (unMStreamF msf) a-  return (b, lifterS f msf')---- ** Another wrapper idea-transS :: (Monad m1, Monad m2)-       => (a2 -> m1 a1)-       -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c))-       -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2-transS transformInput transformOutput msf = MStreamF $ \a2 -> do-    (b2, msf') <- transformOutput a2 $ unMStreamF msf =<< transformInput a2-    return (b2, transS transformInput transformOutput msf')---- ** A more general lifting mechanism that enables recovery.-transG1 :: (Monad m1, Functor m2, Monad m2)-        => (a2 -> m1 a1)-        -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, c))-        -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2-transG1 transformInput transformOutput msf =-  transG transformInput transformOutput' msf-    where-      -- transformOutput' :: forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c)-      transformOutput' a b = second Just <$> transformOutput a b--transG :: (Monad m1, Monad m2)-       => (a2 -> m1 a1)-       -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, Maybe c))-       -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2-transG transformInput transformOutput msf = go-  where go = MStreamF $ \a2 -> do-               (b2, msf') <- transformOutput a2 $ unMStreamF msf =<< transformInput a2-               case msf' of-                 Just msf'' -> return (b2, transG transformInput transformOutput msf'')-                 Nothing    -> return (b2, go)---- transGN :: (Monad m1, Monad m2)---         => (a2 -> m1 a1)---         -> (forall c. a2 -> m1 (b1, c) -> m2 (b2, [c]))---         -> MStreamF m1 a1 b1 -> MStreamF m2 a2 b2--- transGN transformInput transformOutput msf = go---   where go = MStreamF $ \a2 -> do---                (b2, msf') <- transformOutput a2 $ unMStreamF msf =<< transformInput a2---                case msf' of---                  []      -> return (b2, go)---                  [msf''] -> return (b2, transGN transformInput transformOutput msf'')---                  ms      ->---- ** Alternative Reader wrapping/unwrapping MSF combinators-readerS' :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b-readerS' = lifterS wrapReaderT--runReaderS'' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b-runReaderS'' = transG transformInput transformOutput-  where-    transformInput  (_, a) = return a-    transformOutput (s, _) m1 = do (r, c) <- runReaderT m1 s-                                   return (r, Just c)---runStateS''' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)-runStateS''' = transG transformInput transformOutput-  where-    transformInput  (_, a)           = return a-    transformOutput (s, _) msfaction = sym <$> runStateT msfaction s-    sym ((b, msf), s)                = ((s, b), Just msf)--runMaybeS'' :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)-runMaybeS'' = transG transformInput transformOutput-  where-    transformInput       = return-    transformOutput _ m1 = do r <- runMaybeT m1-                              case r of-                                Nothing     -> return (Nothing, Nothing)-                                Just (b, c) -> return (Just b,  Just c)--{--readerS'' :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b-readerS'' = transS transformInput transformOutput-  where-    transformInput :: a -> m (s, a)-    transformInput a = (,) <$> asks <*> pure a-    transformOutput _ = lift--}--runReaderS' :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b-runReaderS' = lifterS unwrapReaderT---- *** Wrapping/unwrapping functions------ IP: Alternative formulation (typechecks just fine):------ FIXME: The foralls may get in the way. They may not be necessary.  MB--- raised the issue already for similar code in Core.----type Wrapper   m1 m2 t1 t2 = forall a b . (t1 a -> m2 b     ) -> (a    -> m1 (t2 b))-type Unwrapper m1 m2 t1 t2 = forall a b . (a    -> m1 (t2 b)) -> (t1 a -> m2 b     )------ Helper type, for when we need some identity * -> * type constructor that--- does not get in the way.----type Id a = a------ And for the Reader, we can now define-type ReaderWrapper   s m = Wrapper   (ReaderT s m) m ((,) s) Id-type ReaderUnwrapper s m = Unwrapper (ReaderT s m) m ((,) s) Id--- and use the types:--- wrapReaderT   :: ReaderWrapper s m--- unwrapReaderT :: ReaderUnwrapper s m--wrapReaderT :: ((s, a) -> m b) -> a -> ReaderT s m b-wrapReaderT g i = ReaderT $ g . flip (,) i--unwrapReaderT :: (a -> ReaderT s m b) -> (s, a) -> m b-unwrapReaderT g i = uncurry (flip runReaderT) $ second g i---- ** Alternative State wrapping/unwrapping MSF combinators------ IPerez: TODO: Is this exactly the same as stateS?-stateS' :: (Functor m, Monad m) => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b-stateS' = lifterS (\g i -> StateT ((resort <$>) . (g . flip (,) i)))- where resort ((s, b), ct) = ((b, ct), s)---- stateS' :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b--- stateS' = lifterS $ \f a -> StateT $ \s -> do---   ((s', b), msf') <- f (s, a)---   return ((b, msf'), s')--runStateS' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)-runStateS' = lifterS (\g i -> resort <$> uncurry (flip runStateT) (second g i))- where resort ((b, msf), s) = ((s, b), msf)---runStateS'' :: (Functor m, Monad m) => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)-runStateS'' = transS transformInput transformOutput-  where-    transformInput  (_, a)           = return a-    transformOutput (s, _) msfaction = sym <$> runStateT msfaction s-    sym ((b, msf), s)                = ((s, b), msf)--{--stateS'' :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b-stateS'' = transS transformInput transformOutput-  where-    transformInput  (_, a) = return a-    transformOutput (s, _) = do-        put s--}--- ** Alternative Writer wrapping/unwrapping MSF combinators-----writerS' :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b-writerS' = lifterS wrapMSFWriterT--runWriterS' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)-runWriterS' = lifterS unwrapMSFWriterT--writerS'' :: (Monad m, Monoid w) => MStreamF m a (w, b) -> MStreamF (WriterT w m) a b-writerS'' = transS transformInput transformOutput-  where-    transformInput = return-    transformOutput _ msfaction = do-        ((w, b), msf') <- lift msfaction-        tell w-        return (b, msf')--runWriterS'' :: (Monoid s, Functor m, Monad m) => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)-runWriterS'' = transS transformInput transformOutput-  where-    transformInput              = return-    transformOutput _ msfaction = sym <$> runWriterT msfaction-    sym ((b, msf), s)           = ((s, b), msf)---- *** Wrapping/unwrapping functions------ TODO: These are *almost*-MSF-agnostic wrapping/unwrapping functions.--- The continuations (and therefore the stream functions) are still--- there, but now we know nothing about them, not even their type.--- Monadic actions carry an extra value, of some polymorphic type ct,--- which is only necessary to extract the output and the context.------ wrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)-wrapMSFWriterT :: (Monoid s, Monad m) => (a -> m ((s, b), ct)) -> a -> WriterT s m (b, ct)-wrapMSFWriterT g i = do-  ((s, b), msf) <- lift $ g i-  tell s-  return (b, msf)--unwrapMSFWriterT :: (Monad m, Functor m) => (a -> WriterT s m (b, ct)) -> a -> m ((s, b), ct)-unwrapMSFWriterT g i = resort <$> runWriterT (g i)-  where resort ((b, msf), s) = ((s, b), msf)---- * Reader monad-readerS :: Monad m => MStreamF m (s, a) b -> MStreamF (ReaderT s m) a b-readerS msf = MStreamF $ \a -> do-  (b, msf') <- ReaderT $ \s -> unMStreamF msf (s, a)-  return (b, readerS msf')--runReaderS :: Monad m => MStreamF (ReaderT s m) a b -> MStreamF m (s, a) b-runReaderS msf = MStreamF $ \(s,a) -> do-  (b, msf') <- runReaderT (unMStreamF msf a) s-  return (b, runReaderS msf')---- ** Auxiliary functions related to ReaderT---- IP: Is runReaderS_ msf s = arr (\a -> (s,a)) >>> runReaderS msf ?--- MB: Yes, but possibly more efficient.-runReaderS_ :: Monad m => MStreamF (ReaderT s m) a b -> s -> MStreamF m a b-runReaderS_ msf s = MStreamF $ \a -> do-    (b, msf') <- runReaderT (unMStreamF msf a) s-    return (b, runReaderS_ msf' s)---- * State monad-stateS :: Monad m => MStreamF m (s, a) (s, b) -> MStreamF (StateT s m) a b-stateS msf = MStreamF $ \a -> StateT $ \s -> do-    ((s', b), msf') <- unMStreamF msf (s, a)-    return ((b, stateS msf'), s')--runStateS :: Monad m => MStreamF (StateT s m) a b -> MStreamF m (s, a) (s, b)-runStateS msf = MStreamF $ \(s, a) -> do-    ((b, msf'), s') <- runStateT (unMStreamF msf a) s-    return ((s', b), runStateS msf')---- ** Auxiliary functions related to StateT---- IP: Is runStateS_ msf s = feedback s $ runStateS msf >>> arr (\(s,b) -> ((s,b), s)) ?-runStateS_ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a (s, b)-runStateS_ msf s = MStreamF $ \a -> do-    ((b, msf'), s') <- runStateT (unMStreamF msf a) s-    return ((s', b), runStateS_ msf' s')---- IP: Is runStateS__ msf s = feedback s $ runStateS msf >>> arr (\(s,b) -> (b, s)) ?-runStateS__ :: Monad m => MStreamF (StateT s m) a b -> s -> MStreamF m a b-runStateS__ msf s = MStreamF $ \a -> do-    ((b, msf'), s') <- runStateT (unMStreamF msf a) s-    return (b, runStateS__ msf' s')---- * Writer monad-writerS :: (Monad m, Monoid s) => MStreamF m a (s, b) -> MStreamF (WriterT s m) a b-writerS msf = MStreamF $ \a -> do-    ((s, b), msf') <- lift $ unMStreamF msf a-    tell s-    return (b, writerS msf')--runWriterS :: Monad m => MStreamF (WriterT s m) a b -> MStreamF m a (s, b)-runWriterS msf = MStreamF $ \a -> do-    ((b, msf'), s') <- runWriterT $ unMStreamF msf a-    return ((s', b), runWriterS msf')---- * RWS (Reader-Writer-State) monad--runRWSS :: (Functor m, Monad m, Monoid w)-        => MStreamF (RWST r w s m) a b-        -> MStreamF m (r, s, a) (w, s, b)-runRWSS = transS transformInput transformOutput-  where-    transformInput  (_, _, a) = return a-    transformOutput (r, s, _) msfaction = sym <$> runRWST msfaction r s-    sym ((b, msf'), s, w) = ((w, s, b), msf')----- * Maybe monad--exit :: Monad m => MStreamF (MaybeT m) a b-exit = MStreamF $ const $ MaybeT $ return Nothing--exitWhen :: Monad m => (a -> Bool) -> MStreamF (MaybeT m) a a-exitWhen condition = go where-    go = MStreamF $ \a -> MaybeT $-        if condition a-        then return Nothing-        else return $ Just (a, go)--exitIf :: Monad m => MStreamF (MaybeT m) Bool ()-exitIf = MStreamF $ \b -> MaybeT $ return $ if b then Nothing else Just ((), exitIf)---- Just a is passed along, Nothing causes the whole MStreamF to exit-maybeExit :: Monad m => MStreamF (MaybeT m) (Maybe a) a-maybeExit = MStreamF $ MaybeT . return . fmap (\x -> (x, maybeExit))--mapMaybeS :: Monad m => MStreamF m a b -> MStreamF m (Maybe a) (Maybe b)-mapMaybeS msf = go-  where-    go = MStreamF $ \maybeA -> case maybeA of-                                 Just a -> do-                                     (b, msf') <- unMStreamF msf a-                                     return (Just b, mapMaybeS msf')-                                 Nothing -> return (Nothing, go)---- mapMaybeS msf == runMaybeS (inMaybeT >>> lift mapMaybeS)--inMaybeT :: Monad m => MStreamF (MaybeT m) (Maybe a) a-inMaybeT = liftMStreamF $ MaybeT . return--{--maybeS :: Monad m => MStreamF m a (Maybe b) -> MStreamF (MaybeT m) a b-maybeS msf = MStreamF $ \a -> MaybeT $ return $ unMStreamF msf a--- maybeS msf == lift msf >>> inMaybeT--}--runMaybeS :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)-runMaybeS msf = go-  where-    go = MStreamF $ \a -> do-           bmsf <- runMaybeT $ unMStreamF msf a-           case bmsf of-             Just (b, msf') -> return (Just b, runMaybeS msf')-             Nothing        -> return (Nothing, go)--{---- MB: Doesn't typecheck, I don't know why------ IP: Because of the forall in runTS.------ From the action runMaybeT msfaction it does not know that--- the second element of the pair in 'thing' will be a continuation.------ The first branch of the case works because you are passing the--- msf' as is.------ In the second one, you are passing msf, which has the specific type--- MStreamF (MaybeT m) a b.------ Two things you can try (to help you see that this is indeed why GHC is--- complaining):---   - Make the second continuation undefined. Then it typechecks.---   - Use ScopedTypeVariables and a let binding to type msf' in the---   first branch of the case selector. It'll complain about the type---   of msf' if you say it's forcibly a MStreamF (MaybeT m) a b.-----runMaybeS'' :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a (Maybe b)-runMaybeS'' msf = transS transformInput transformOutput msf-  where-    transformInput  = return-    transformOutput _ msfaction = do-      thing <- runMaybeT msfaction-      case thing of-        Just (b, msf') -> return (Just b, msf')-        Nothing        -> return (Nothing, msf)--}--untilMaybe :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF (MaybeT m) a b-untilMaybe msf cond = proc a -> do-    b <- liftMStreamFTrans msf -< a-    c <- liftMStreamFTrans cond -< b-    inMaybeT -< if c then Nothing else Just b--catchMaybe :: Monad m => MStreamF (MaybeT m) a b -> MStreamF m a b -> MStreamF m a b-catchMaybe msf1 msf2 = MStreamF $ \a -> do-    cont <- runMaybeT $ unMStreamF msf1 a-    case cont of-        Just (b, msf1') -> return (b, msf1' `catchMaybe` msf2)-        Nothing         -> unMStreamF msf2 a----- * Exception monad--{--catchS' :: Monad m => MStreamF (ExceptT e m) a b -> (e -> m (b, MStreamF m a b)) -> MStreamF m a b-catchS' msf f = MStreamF $ \a -> (unMStreamF msf a) f `catchFinal` f--}-catchS :: Monad m => MStreamF (ExceptT e m) a b -> (e -> MStreamF m a b) -> MStreamF m a b-catchS msf f = MStreamF $ \a -> do-    cont <- runExceptT $ unMStreamF msf a-    case cont of-        Left e          -> unMStreamF (f e) a-        Right (b, msf') -> return (b, msf' `catchS` f)--exceptS :: Monad m => MStreamF (ExceptT e m) a b -> MStreamF m a (Either e b)-exceptS msf = go- where-   go = MStreamF $ \a -> do-          cont <- runExceptT $ unMStreamF msf a-          case cont of-            Left e          -> return (Left e,  go)-            Right (b, msf') -> return (Right b, exceptS msf')---- catchFinal :: Monad m => ExceptT e m a -> (e -> m a) -> m a--- catchFinal action f = do---     ea <- runExceptT action---     case ea of---         Left  e -> f e---         Right a -> return a---throwOnCond :: Monad m => (a -> Bool) -> e -> MStreamF (ExceptT e m) a a-throwOnCond cond e = proc a -> if cond a-    then liftMStreamF throwE -< e-    else returnA -< a--throwOnCondM :: Monad m => (a -> m Bool) -> e -> MStreamF (ExceptT e m) a a-throwOnCondM cond e = proc a -> do-    b <- liftMStreamF (lift . cond) -< a-    if b-    then liftMStreamF throwE -< e-    else returnA -< a---throwOn :: Monad m => e -> MStreamF (ExceptT e m) Bool ()-throwOn e = proc b -> throwOn' -< (b, e)--throwOn' :: Monad m => MStreamF (ExceptT e m) (Bool, e) ()-throwOn' = proc (b, e) -> if b-    then liftMStreamF throwE -< e-    else returnA -< ()---- Similar to delayed switching. Looses a b in case of exception-untilE :: Monad m => MStreamF m a b -> MStreamF m b (Maybe e)-       -> MStreamF (ExceptT e m) a b-untilE msf msfe = proc a -> do-    b <- liftMStreamFTrans msf -< a-    me <- liftMStreamFTrans msfe -< b-    inExceptT -< (ExceptT . return) (maybe (Right b) Left me)--throwMaybe :: Monad m => MStreamF (ExceptT e m) (Maybe e) (Maybe a)-throwMaybe = mapMaybeS $ liftMStreamF throwE--throwS :: Monad m => MStreamF (ExceptT e m) e a-throwS = liftMStreamF throwE--inExceptT :: Monad m => MStreamF (ExceptT e m) (ExceptT e m a) a-inExceptT = liftMStreamF id -- extracts value from monadic action---- * List monad---- Name alternative (in the article): collect-widthFirst :: (Functor m, Monad m) => MStreamF (ListT m) a b -> MStreamF m a [b]-widthFirst msf = widthFirst' [msf] where-    widthFirst' msfs = MStreamF $ \a -> do-        (bs, msfs') <- unzip . concat <$> mapM (runListT . flip unMStreamF a) msfs-        return (bs, widthFirst' msfs')----- Name alternatives: "choose", "parallely" (problematic because it's not multicore)-sequenceS :: Monad m => [MStreamF m a b] -> MStreamF (ListT m) a b-sequenceS msfs = MStreamF $ \a -> ListT $ sequence $ apply a <$> msfs-  where-    apply a msf = do-        (b, msf') <- unMStreamF msf a-        return (b, sequenceS [msf'])--- sequenceS = foldl (<+>) arrowzero . map liftMStreamFTrans
src/Data/MonadicStreamFunction.hs view
@@ -1,168 +1,51 @@ -- | Monadic Stream Functions are synchronized stream functions--- with side effects.+--   with side effects.+--+--   MSFs are defined by a function @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@+--   that executes one step of a simulation, and produces an output in a+--   monadic context, and a continuation to be used for future steps.+--+--   See the module "Data.MonadicStreamFunction.Core" for details.+--+--   MSFs are a generalisation of the implementation mechanism used by Yampa,+--   Wormholes and other FRP and reactive implementations.+--+--   When combined with different monads, they produce interesting effects. For+--   example, when combined with the @Maybe@ monad, they become transformations+--   that may stop producing outputs (and continuations). The @Either@ monad+--   gives rise to MSFs that end with a result (akin to Tasks in Yampa, and+--   Monadic FRP).+--+--   Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a b@+--   for a specific transformer @t@ often gives rise to known FRP constructs.+--   For instance, flattening with @EitherT@ gives rise to switching, and+--   flattening with @ListT@ gives rise to parallelism with broadcasting.+--+--   MSFs can be used to implement many FRP variants, including Arrowized FRP,+--   Classic FRP, and plain reactive programming. Arrowized and applicative+--   syntax are both supported.+--+--   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>).+ module Data.MonadicStreamFunction   ( module Control.Arrow-  , module Data.MonadicStreamFunction   , module X   )  where  -- External-import Control.Applicative+ import Control.Arrow-import Control.Category (Category(..))-import Control.Monad-import Control.Monad.Base-import Data.Monoid-import Prelude hiding ((.), id, sum) --- Internal (generic)-import Data.VectorSpace-import Data.VectorSpace.Instances()+-- Internal  import Data.MonadicStreamFunction.Core        as X-import Data.MonadicStreamFunction.ArrowChoice as X-import Data.MonadicStreamFunction.ArrowLoop   as X-import Data.MonadicStreamFunction.ArrowPlus   as X---- ** Instances for monadic streams--instance Functor m => Functor (MStreamF m r)-  where-    -- fmap f as = as >>> arr f-    fmap f as = MStreamF $ \r -> fTuple <$> unMStreamF as r-      where-        fTuple (a, as') = (f a, f <$> as')--instance Applicative m => Applicative (MStreamF m r) where-  -- pure a = constantly a-  pure a = MStreamF $ \_ -> pure (a, pure a)-  {--  fs <*> as = proc _ -> do-      f <- fs -< ()-      a <- as -< ()-      returnA -< f a-  -}-  fs <*> as = MStreamF $ \r -> applyTuple <$> unMStreamF fs r <*> unMStreamF as r-    where-      applyTuple (f, fs') (a, as') = (f a, fs' <*> as')---- ** Lifts--{-# DEPRECATED insert "Don't use this. liftMStreamF id instead" #-}-insert :: Monad m => MStreamF m (m a) a-insert = liftMStreamF id--- This expands to the old code:------ MStreamF $ \ma -> do---   a <- ma---   return (a, insert)--liftMStreamF_ :: Monad m => m b -> MStreamF m a b-liftMStreamF_ = liftMStreamF . const---- * Monadic lifting from one monad into another---- ** Monad stacks--(^>>>) :: MonadBase m1 m2 => MStreamF m1 a b -> MStreamF m2 b c -> MStreamF m2 a c-sf1 ^>>> sf2 = (liftMStreamFBase sf1) >>> sf2-{-# INLINE (^>>>) #-}--(>>>^) :: MonadBase m1 m2 => MStreamF m2 a b -> MStreamF m1 b c -> MStreamF m2 a c-sf1 >>>^ sf2 = sf1 >>> (liftMStreamFBase sf2)-{-# INLINE (>>>^) #-}---- ** Delays and signal overwriting---- See also: 'iPre'--iPost :: Monad m => b -> MStreamF m a b -> MStreamF m a b-iPost b sf = MStreamF $ \_ -> return (b, sf)--next :: Monad m => b -> MStreamF m a b -> MStreamF m a b-next b sf = MStreamF $ \a -> do-  (b', sf') <- unMStreamF sf a-  return (b, next b' sf')--- rather, once delay is tested:--- next b sf = sf >>> delay b---- ** Switching---- See also: 'switch', and the exception monad combinators for MSFs in--- Control.Monad.Trans.MStreamF--untilS :: Monad m => MStreamF m a b -> MStreamF m b Bool -> MStreamF m a (b, Maybe ())-untilS sf1 sf2 = sf1 >>> (arr id &&& (sf2 >>> arr boolToMaybe))-  where boolToMaybe x = if x then Just () else Nothing--andThen :: Monad m => MStreamF m a (b, Maybe ()) -> MStreamF m a b -> MStreamF m a b-andThen sf1 sf2 = switch sf1 $ const sf2---- ** Feedback loops---- | Missing: 'feedback'---- * Adding side effects-withSideEffect :: Monad m => (a -> m b) -> MStreamF m a a-withSideEffect method = (id &&& liftMStreamF method) >>> arr fst--withSideEffect_ :: Monad m => m b -> MStreamF m a a-withSideEffect_ method = withSideEffect $ const method---- * Debugging--traceGeneral :: (Monad m, Show a) => (String -> m ()) -> String -> MStreamF m a a-traceGeneral method msg =-  withSideEffect (method . (msg ++) . show)--trace :: Show a => String -> MStreamF IO a a-trace = traceGeneral putStrLn---- FIXME: This does not seem to be a very good name.  It should be--- something like traceWith. It also does too much.-pauseOnGeneral :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MStreamF m a a-pauseOnGeneral cond method msg = withSideEffect $ \a ->-  when (cond a) $ method $ msg ++ show a--pauseOn :: Show a => (a -> Bool) -> String -> MStreamF IO a a-pauseOn cond = pauseOnGeneral cond $ \s -> print s >> getLine >> return ()---- * Tests and examples--sum :: (Monoid n, Monad m) => MStreamF m n n-sum = sumFrom mempty-{-# INLINE sum #-}--sumFrom :: (Monoid n, Monad m) => n -> MStreamF m n n-sumFrom n0 = MStreamF $ \n -> let acc = n0 `mappend` n-                              -- in acc `seq` return (acc, sumFrom acc)-                              in return (acc, sumFrom acc)--- sum = feedback 0 (arr (uncurry (+) >>> dup))---  where dup x = (x,x)--count :: (Num n, Monad m) => MStreamF m () n-count = arr (const (Sum 1)) >>> sum >>> arr getSum--unfold :: Monad m => (a -> (b,a)) -> a -> MStreamF m () b-unfold f a = MStreamF $ \_ -> let (b,a') = f a in b `seq` return (b, unfold f a')--- unfold f x = feedback x (arr (snd >>> f))--repeatedly :: Monad m => (a -> a) -> a -> MStreamF m () a-repeatedly f = repeatedly'- where repeatedly' a = MStreamF $ \() -> let a' = f a in a' `seq` return (a, repeatedly' a')--- repeatedly f x = feedback x (arr (f >>> \x -> (x,x)))+import Data.MonadicStreamFunction.Util        as X --- FIXME: This should *not* be in this module-mapMStreamF :: Monad m => MStreamF m a b -> MStreamF m [a] [b]-mapMStreamF sf = MStreamF $ consume sf-  where-    consume :: Monad m => MStreamF m a t -> [a] -> m ([t], MStreamF m [a] [t])-    consume sf []     = return ([], mapMStreamF sf)-    consume sf (a:as) = do-      (b, sf')   <- unMStreamF sf a-      (bs, sf'') <- consume sf' as-      b `seq` return (b:bs, sf'')+-- Internal (Instances) --- * Streams (or generators)-type MStream m a = MStreamF m () a+import Data.MonadicStreamFunction.ArrowChoice ()+import Data.MonadicStreamFunction.ArrowLoop   ()+import Data.MonadicStreamFunction.ArrowPlus   ()
src/Data/MonadicStreamFunction/ArrowChoice.hs view
@@ -1,12 +1,13 @@+{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.MonadicStreamFunction.ArrowChoice where  import Control.Arrow  import Data.MonadicStreamFunction.Core -instance Monad m => ArrowChoice (MStreamF m) where-  left sf = MStreamF f+instance Monad m => ArrowChoice (MSF m) where+  left sf = MSF f     where-      f (Left a) = do (b, sf') <- unMStreamF sf a+      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 view
@@ -1,16 +1,15 @@-{-# LANGUAGE RecursiveDo #-}+{-# LANGUAGE RecursiveDo          #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.MonadicStreamFunction.ArrowLoop where  import Data.MonadicStreamFunction.Core  -- External import Control.Arrow-import Control.Category (Category(..))-import Control.Monad import Control.Monad.Fix -instance (Monad m, MonadFix m) => ArrowLoop (MStreamF m) where+instance (Monad m, MonadFix m) => ArrowLoop (MSF m) where   -- loop :: a (b, d) (c, d) -> a b c-  loop sf = MStreamF $ \a -> do-              rec ((b,c), sf') <- unMStreamF sf (a, c)+  loop sf = MSF $ \a -> do+              rec ((b,c), sf') <- unMSF sf (a, c)               return (b, loop sf')
src/Data/MonadicStreamFunction/ArrowPlus.hs view
@@ -1,3 +1,4 @@+{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.MonadicStreamFunction.ArrowPlus where  import Control.Arrow@@ -5,8 +6,8 @@  import Data.MonadicStreamFunction.Core -instance (Monad m, MonadPlus m) => ArrowZero (MStreamF m) where-  zeroArrow = MStreamF $ const mzero+instance (Monad m, MonadPlus m) => ArrowZero (MSF m) where+  zeroArrow = MSF $ const mzero -instance (Monad m, MonadPlus m) => ArrowPlus (MStreamF m) where-  sf1 <+> sf2 = MStreamF $ \a -> unMStreamF sf1 a `mplus` unMStreamF sf2 a+instance (Monad m, MonadPlus m) => ArrowPlus (MSF m) where+  sf1 <+> sf2 = MSF $ \a -> unMSF sf1 a `mplus` unMSF sf2 a
src/Data/MonadicStreamFunction/Core.hs view
@@ -1,12 +1,40 @@ {-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE Rank2Types     #-} -- | Monadic Stream Functions are synchronized stream functions--- with side effects.+--   with side effects.+--+--   MSFs are defined by a function @unMSF :: MSF m a b -> a -> m (b, MSF m a b)@+--   that executes one step of a simulation, and produces an output in a+--   monadic context, and a continuation to be used for future steps.+--+--   MSFs are a generalisation of the implementation mechanism used by Yampa,+--   Wormholes and other FRP and reactive implementations.+--+--   When combined with different monads, they produce interesting effects. For+--   example, when combined with the @Maybe@ monad, they become transformations+--   that may stop producing outputs (and continuations). The @Either@ monad+--   gives rise to MSFs that end with a result (akin to Tasks in Yampa, and+--   Monadic FRP).+--+--   Flattening, that is, going from some structure @MSF (t m) a b@ to @MSF m a b@+--   for a specific transformer @t@ often gives rise to known FRP constructs.+--   For instance, flattening with @EitherT@ gives rise to switching, and+--   flattening with @ListT@ gives rise to parallelism with broadcasting.+--+--   MSFs can be used to implement many FRP variants, including Arrowized FRP,+--   Classic FRP, and plain reactive programming. Arrowized and applicative+--   syntax are both supported.+--+--   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>). +-- NOTE TO IMPLEMENTORS:+-- -- This module contains the core. Only the core. It should be possible -- to define every function and type outside this module, except for the -- instances for ArrowLoop, ArrowChoice, etc., without access to the--- internal constructor for MStreamF and the function 'unMStreamF'.+-- internal constructor for MSF and the function 'unMSF'. -- -- It's very hard to know what IS essential to framework and if we start -- adding all the functions and instances that *may* be useful in one@@ -19,126 +47,170 @@ -- -- To address potential violations of basic design principles (like 'not -- having orphan instances'), the main module Data.MonadicStreamFunction--- exports everything. Users should *never* import this module+-- exports everything. Users should *never* import this module here -- individually, but the main module instead. module Data.MonadicStreamFunction.Core where  -- External-import Control.Applicative import Control.Arrow+import Control.Applicative import Control.Category (Category(..)) import Control.Monad import Control.Monad.Base import Control.Monad.Trans.Class import Prelude hiding ((.), id, sum) --- MStreamF: Stepwise, side-effectful MStreamFs without implicit knowledge of time-data MStreamF m a b = MStreamF { unMStreamF :: a -> m (b, MStreamF m a b) }+-- * Definitions -instance Monad m => Category (MStreamF m) where+-- | Stepwise, side-effectful MSFs without implicit knowledge of time.+--+-- MSFs should be applied to streams or executed indefinitely or until they+-- terminate. See 'reactimate' and 'reactimateB' for details. In general,+-- calling the value constructor 'MSF' or the function 'unMSF' is discouraged.+data MSF m a b = MSF { unMSF :: a -> m (b, MSF m a b) }++-- Instances++instance Monad m => Category (MSF m) where   id = go-    where go = MStreamF $ \a -> return (a, go)-  sf2 . sf1 = MStreamF $ \a -> do-    (b, sf1') <- unMStreamF sf1 a-    (c, sf2') <- unMStreamF sf2 b+    where go = MSF $ \a -> return (a, go)+  sf2 . sf1 = MSF $ \a -> do+    (b, sf1') <- unMSF sf1 a+    (c, sf2') <- unMSF sf2 b     let sf' = sf2' . sf1'     c `seq` return (c, sf') -instance Monad m => Arrow (MStreamF m) where+instance Monad m => Arrow (MSF m) where    arr f = go-    where go = MStreamF $ \a -> return (f a, go)+    where go = MSF $ \a -> return (f a, go) -  first sf = MStreamF $ \(a,c) -> do-    (b, sf') <- unMStreamF sf a+  first sf = MSF $ \(a,c) -> do+    (b, sf') <- unMSF sf a     b `seq` return ((b, c), first sf')-    -- This is called the "monadic strength" of m --- ** Lifts-liftMStreamF :: Monad m => (a -> m b) -> MStreamF m a b-liftMStreamF f = go- where go = MStreamF $ \a -> do-              b <- f a-              return (b, go)+instance Functor m => Functor (MSF m a) where+  -- fmap f msf == msf >>> arr f+  fmap f msf = MSF $ fmap fS . unMSF msf+    where+      fS (b, cont) = (f b, fmap f cont) +instance (Functor m, Monad m) => Applicative (MSF m a) where+  -- It is possible to define this instance with only Applicative m+  pure = arr . const+  fs <*> bs = (fs &&& bs) >>> arr (uncurry ($))++-- * Lifting++-- | Apply the same monadic transformation to every element of the input stream.+--+-- Generalisation of arr from Arrow to stream functions with monads.+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 +liftS :: (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b+liftS = arrM . (liftBase .)+ -- ** Purer monads  -- IPerez: There is an alternative signature for liftMStreamPurer that also -- works, and makes the code simpler: ----- liftMStreamFPurer :: Monad m => (m1 (b, MStreamF m1 a b) -> m (b, MStreamF m1 a b)) -> MStreamF m1 a b -> MStreamF m a b+-- liftMSFPurer :: Monad m => (m1 (b, MSF m1 a b) -> m (b, MSF m1 a b)) -> MSF m1 a b -> MSF m a b -- -- Then we can express: ----- liftMStreamFTrans = liftMStreamFPurer lift--- liftMStreamFBase  = liftMStreamFPurer liftBase+-- liftMSFTrans = liftMSFPurer lift+-- liftMSFBase  = liftMSFPurer liftBase ----- We could also define a strict version of liftMStreamFPurer as follows:+-- We could also define a strict version of liftMSFPurer as follows: ----- liftMStreamPurer' f = liftMStreamFPurer (f >=> whnfVal)+-- liftMStreamPurer' f = liftMSFPurer (f >=> whnfVal) --   where whnfVal p@(b,_) = b `seq` return p ----- and leave liftMStreamFPurer as a lazy version (by default).+-- and leave liftMSFPurer as a lazy version (by default).  -- | Lifting purer monadic actions (in an arbitrary way)-liftMStreamFPurer :: (Monad m2, Monad m1) => (forall c . m1 c -> m2 c) -> MStreamF m1 a b -> MStreamF m2 a b-liftMStreamFPurer liftPurer sf = MStreamF $ \a -> do-  (b, sf') <- liftPurer $ unMStreamF sf a-  b `seq` return (b, liftMStreamFPurer liftPurer sf')+liftMSFPurer :: (Monad m2, Monad m1) => (forall c . m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b+liftMSFPurer liftPurer sf = MSF $ \a -> do+  (b, sf') <- liftPurer $ unMSF sf a+  b `seq` return (b, liftMSFPurer liftPurer sf')  -- ** Monad stacks --- | Lifting inner monadic actions in monad stacks+-- | Lift inner monadic actions in monad stacks.+ -- TODO Should be able to express this in terms of MonadBase-liftMStreamFTrans :: (MonadTrans t, Monad m, Monad (t m)) => MStreamF m a b -> MStreamF (t m) a b-liftMStreamFTrans sf = MStreamF $ \a -> do-  (b, sf') <- lift $ unMStreamF sf a-  return (b, liftMStreamFTrans sf')+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') --- | Lifting the innest monadic actions in a monad stacks (generalisation of liftIO)-liftMStreamFBase :: (Monad m2, MonadBase m1 m2) => MStreamF m1 a b -> MStreamF m2 a b-liftMStreamFBase sf = MStreamF $ \a -> do-  (b, sf') <- liftBase $ unMStreamF sf a-  b `seq` return (b, liftMStreamFBase 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 --- | Extract MSF from a monadic action-performOnFirstSample :: Monad m => m (MStreamF m a b) -> MStreamF m a b-performOnFirstSample sfaction = MStreamF $ \a -> do+-- | Extract MSF from a monadic action.+--+-- Runs a monadic action that produces an MSF on the first iteration/step, and+-- uses that MSF as the main signal function for all inputs (including the+-- first one).+performOnFirstSample :: Monad m => m (MSF m a b) -> MSF m a b+performOnFirstSample sfaction = MSF $ \a -> do   sf <- sfaction-  unMStreamF sf a+  unMSF sf a  -- ** Delays and signal overwriting -iPre :: Monad m => a -> MStreamF m a a-iPre firsta = MStreamF $ \a -> return (firsta, delay a)+-- | Delay a signal by one sample.+iPre :: Monad m+     => a         -- ^ First output+     -> MSF m a a+iPre firsta = MSF $ \a -> return (firsta, delay a) -- iPre firsta = feedback firsta $ lift swap --   where swap (a,b) = (b, a) -- iPre firsta = next firsta identity +-- | See 'iPre'.+ -- FIXME: Remove delay from this module. We should try to make this module -- small, keeping only primitives.-delay :: Monad m => a -> MStreamF m a a+delay :: Monad m => a -> MSF m a a delay = iPre  -- ** Switching -switch :: Monad m => MStreamF m a (b, Maybe c) -> (c -> MStreamF m a b) -> MStreamF m a b-switch sf f = MStreamF $ \a -> do-  ((b, c), sf') <- unMStreamF sf a+-- | Switching applies one MSF until it produces a 'Just' output, and then+-- "turns on" a continuation and runs it.+--+-- A more advanced and comfortable approach to switching is givin by Exceptions+-- in "Control.Monad.Trans.MSF.Except"+switch :: Monad m => MSF m a (b, Maybe c) -> (c -> MSF m a b) -> MSF m a b+switch sf f = MSF $ \a -> do+  ((b, c), sf') <- unMSF sf a   return (b, maybe (switch sf' f) f c)  -- ** Feedback loops -feedback :: Monad m => c -> MStreamF m (a, c) (b, c) -> MStreamF m a b-feedback c sf = MStreamF $ \a -> do-  ((b', c'), sf') <- unMStreamF sf (a, c)+-- | 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+feedback c sf = MSF $ \a -> do+  ((b', c'), sf') <- unMSF sf (a, c)   return (b', feedback c' sf') --- * Reactimating+-- * Execution/simulation  -- | Apply a monadic stream function to a list. --@@ -148,26 +220,28 @@ -- if the MSF produces Nothing at any point, so the output stream cannot -- consumed progressively. ----- To explore the output progressively, use liftMStreamF and (>>>), together+-- To explore the output progressively, use liftMSF and (>>>), together -- with some action that consumes/actuates on the output. -- -- This is called "runSF" in Liu, Cheng, Hudak, "Causal Commutative Arrows and -- Their Optimization"-embed :: Monad m => MStreamF m a b -> [a] -> m [b]+embed :: Monad m => MSF m a b -> [a] -> m [b] embed _  []     = return [] embed sf (a:as) = do-  (b, sf') <- unMStreamF sf a+  (b, sf') <- unMSF sf a   bs       <- embed sf' as   return (b:bs) --- | Runs an MSF indefinitely passing a unit-carrying input stream.-reactimate :: Monad m => MStreamF m () () -> m ()+-- | Run an MSF indefinitely passing a unit-carrying input stream.+reactimate :: Monad m => MSF m () () -> m () reactimate sf = do-  (_, sf') <- unMStreamF sf ()+  (_, sf') <- unMSF sf ()   reactimate sf' --- | Runs an MSF indefinitely passing a unit-carrying input stream.-reactimateB :: Monad m => MStreamF m () Bool -> m ()+-- | 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+reactimateB :: Monad m => MSF m () Bool -> m () reactimateB sf = do-  (b, sf') <- unMStreamF sf ()-  if b then return () else reactimateB sf'+  (b, sf') <- unMSF sf ()+  unless b $ reactimateB sf'
src/Data/MonadicStreamFunction/Instances.hs view
@@ -1,16 +1,15 @@-{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeFamilies #-} module Data.MonadicStreamFunction.Instances where  -- External import Control.Arrow  -- Internal-import Control.Arrow.Util import Data.MonadicStreamFunction.Core  -- Numerical operations are defined elementwise on the output-elementwise :: Monad m => (b -> c) -> MStreamF m a b -> MStreamF m a c+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) -> MStreamF m a b -> MStreamF m a c -> MStreamF m a d+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/Num.hs view
@@ -1,41 +1,41 @@-{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeFamilies         #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.MonadicStreamFunction.Instances.Num where - import Control.Arrow.Util import Data.MonadicStreamFunction.Core import Data.MonadicStreamFunction.Instances -instance (Monad m, Num b) => Num (MStreamF m a b) where-    (+)         = elementwise2 (+)-    (-)         = elementwise2 (-)-    (*)         = elementwise2 (*)-    abs         = elementwise abs-    signum      = elementwise signum-    negate      = elementwise negate-    fromInteger = constantly . fromInteger+instance (Monad m, Num b) => Num (MSF m a b) where+  (+)         = elementwise2 (+)+  (-)         = elementwise2 (-)+  (*)         = elementwise2 (*)+  abs         = elementwise abs+  signum      = elementwise signum+  negate      = elementwise negate+  fromInteger = constantly . fromInteger -instance (Monad m, Fractional b) => Fractional (MStreamF m a b) where-    fromRational = constantly . fromRational-    (/)          = elementwise2 (/)-    recip        = elementwise recip+instance (Monad m, Fractional b) => Fractional (MSF m a b) where+  fromRational = constantly . fromRational+  (/)          = elementwise2 (/)+  recip        = elementwise recip -instance (Monad m, Floating b) => Floating (MStreamF m a b) where-    pi      = constantly   pi-    exp     = elementwise  exp-    log     = elementwise  log-    sqrt    = elementwise  sqrt-    (**)    = elementwise2 (**)-    logBase = elementwise2 logBase-    sin     = elementwise  sin-    cos     = elementwise  cos-    tan     = elementwise  tan-    asin    = elementwise  asin-    acos    = elementwise  acos-    atan    = elementwise  atan-    sinh    = elementwise  sinh-    cosh    = elementwise  cosh-    tanh    = elementwise  tanh-    asinh   = elementwise  asinh-    acosh   = elementwise  acosh-    atanh   = elementwise  atanh+instance (Monad m, Floating b) => Floating (MSF m a b) where+  pi      = constantly   pi+  exp     = elementwise  exp+  log     = elementwise  log+  sqrt    = elementwise  sqrt+  (**)    = elementwise2 (**)+  logBase = elementwise2 logBase+  sin     = elementwise  sin+  cos     = elementwise  cos+  tan     = elementwise  tan+  asin    = elementwise  asin+  acos    = elementwise  acos+  atan    = elementwise  atan+  sinh    = elementwise  sinh+  cosh    = elementwise  cosh+  tanh    = elementwise  tanh+  asinh   = elementwise  asinh+  acosh   = elementwise  acosh+  atanh   = elementwise  atanh
src/Data/MonadicStreamFunction/Instances/VectorSpace.hs view
@@ -1,21 +1,20 @@-{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeFamilies         #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.MonadicStreamFunction.Instances.VectorSpace where - 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 (MStreamF m a v) where-    type Groundring (MStreamF m a v) = Groundring v-    zeroVector   = constantly zeroVector-    r *^ msf     = elementwise (r *^) msf-    negateVector = elementwise negateVector-    (^+^)        = elementwise2 (^+^)-    (^-^)        = elementwise2 (^-^)+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+  (^+^)        = elementwise2 (^+^)+  (^-^)        = elementwise2 (^-^) -instance (Monad m, VectorSpace v) => VectorSpace (MStreamF m a v) where-    msf ^/ r = elementwise (^/ r) msf+instance (Monad m, VectorSpace v) => VectorSpace (MSF m a v) where+  msf ^/ r = elementwise (^/ r) msf
src/Data/MonadicStreamFunction/Parallel.hs view
@@ -16,12 +16,12 @@ -- and so (***) might be strict in both arguments and not take -- full advantage of parallelism. ---(*|*) :: Monad m => MStreamF m a b -> MStreamF m c d -> MStreamF m (a, c) (b, d)-msf1 *|* msf2 = MStreamF $ \(a, c) -> do-    (b, msf1') <- unMStreamF msf1 a-    (d, msf2') <- unMStreamF msf2 c+(*|*) :: 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')  -(&|&) :: Monad m => MStreamF m a b -> MStreamF m a c -> MStreamF m a (b, c)+(&|&) :: 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/ReactHandle.hs view
@@ -0,0 +1,45 @@+-- | ReactHandle++-- Sometimes it is beneficial to give control to an external main loop,+-- for example OpenGL or a hardware-clocked audio server like JACK.+-- This module makes Dunai compatible with external main loops.++module Data.MonadicStreamFunction.ReactHandle where++-- External+import Control.Monad.IO.Class+import Data.IORef++-- Internal+import Data.MonadicStreamFunction+++-- | A storage for the current state of an MSF+type ReactHandle m = IORef (MSF m () ())+++-- | Needs to be called before the external main loop is dispatched+reactInit :: MonadIO m => MSF m () () -> m (ReactHandle m)+reactInit = liftIO . newIORef+++-- | The callback that needs to be called by the main loop at every cycle+react :: MonadIO m => ReactHandle m -> m ()+react handle = do+  msf <- liftIO $ readIORef handle+  (_, msf') <- unMSF msf ()+  liftIO $ writeIORef handle msf'+++-- | Creates two ends of a synchronisation wormhole++-- Often, the external framework may have several parallel loops,+-- for example, OpenGL with a display callback, an idle callback and a keyboard callback.+-- In such cases, one would like to let the different parts communicate.+-- This is done through a wormhole, which is a shared mutable variable+-- that can be written from one part and read from the other.++createWormhole :: MonadIO m => a -> m (MSF m a (), MSF m () a)+createWormhole a = liftIO $ do+  ref <- newIORef a+  return (arrM $ liftIO . writeIORef ref, arrM_ $ liftIO $ readIORef ref)
+ src/Data/MonadicStreamFunction/Util.hs view
@@ -0,0 +1,148 @@+module Data.MonadicStreamFunction.Util where++-- External+import Control.Applicative+import Control.Arrow+import Control.Category+import Control.Monad+import Control.Monad.Base+import Data.Monoid+import Prelude hiding (id, (.))++-- Internal+import Data.MonadicStreamFunction.Core+import Data.VectorSpace++-- * Useful aliases+type MStream m a = MSF m () a+type MSink   m a = MSF m a ()+++-- * Stateful accumulation++accumulateWith :: Monad m => (a -> s -> s) -> s -> MSF m a s+accumulateWith f s0 = feedback s0 $ arr g+  where+    g (a, s) = let s' = f a s in (s', s')++-- ** Accumulation for monoids++mappendS :: (Monoid n, Monad m) => MSF m n n+mappendS = mappendFrom mempty+{-# INLINE mappendS #-}++mappendFrom :: (Monoid n, Monad m) => n -> MSF m n n+mappendFrom = accumulateWith mappend++-- ** Accumulation for VectorSpace instances++sumFrom :: (RModule v, Monad m) => v -> MSF m v v+sumFrom = accumulateWith (^+^)++sumS :: (RModule v, Monad m) => MSF m v v+sumS = sumFrom zeroVector++count :: (Num n, Monad m) => MSF m a n+count = arr (const 1) >>> accumulateWith (+) 0++-- * Generating Signals++unfold :: Monad m => (a -> (b,a)) -> a -> MSF m () b+unfold f a = MSF $ \_ -> let (b,a') = f a in b `seq` return (b, unfold f a')+-- unfold f x = feedback x (arr (snd >>> f))++repeatedly :: Monad m => (a -> a) -> a -> MSF m () a+repeatedly f = repeatedly'+ 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++mapMSF :: Monad m => MSF m a b -> MSF m [a] [b]+mapMSF = MSF . consume+  where+    consume :: Monad m => MSF m a t -> [a] -> m ([t], MSF m [a] [t])+    consume sf []     = return ([], mapMSF sf)+    consume sf (a:as) = do+      (b, sf')   <- unMSF sf a+      (bs, sf'') <- consume sf' as+      b `seq` return (b:bs, sf'')++mapMaybeS :: Monad m => MSF m a b -> MSF m (Maybe a) (Maybe b)+mapMaybeS msf = go+  where+    go = MSF $ \maybeA -> case maybeA of+      Just a -> do+        (b, msf') <- unMSF msf a+        return (Just b, mapMaybeS msf')+      Nothing -> return (Nothing, go)++++-- * Adding side effects+withSideEffect :: Monad m => (a -> m b) -> MSF m a a+withSideEffect method = (id &&& arrM method) >>> arr fst++withSideEffect_ :: Monad m => m b -> MSF m a a+withSideEffect_ method = withSideEffect $ const method++-- * Debugging++traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a+traceWith method msg =+  withSideEffect (method . (msg ++) . show)++trace :: Show a => String -> MSF IO a a+trace = traceWith putStrLn++traceWhen :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MSF m a a+traceWhen cond method msg = withSideEffect $ \a ->+  when (cond a) $ method $ msg ++ show a++pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a+pauseOn cond = traceWhen cond $ \s -> print s >> getLine >> return ()+++-- * Inserting monadic actions into MSFs++{-# DEPRECATED insert "Don't use this. arrM id instead" #-}+insert :: Monad m => MSF m (m a) a+insert = arrM id++arrM_ :: Monad m => m b -> MSF m a b+arrM_ = arrM . const++-- * Lifting from one monad into another+++(^>>>) :: MonadBase m1 m2 => MSF m1 a b -> MSF m2 b c -> MSF m2 a c+sf1 ^>>> sf2 = liftMSFBase sf1 >>> sf2+{-# INLINE (^>>>) #-}++(>>>^) :: MonadBase m1 m2 => MSF m2 a b -> MSF m1 b c -> MSF m2 a c+sf1 >>>^ sf2 = sf1 >>> liftMSFBase sf2+{-# INLINE (>>>^) #-}++-- * Delays and signal overwriting++-- See also: 'iPre'++iPost :: Monad m => b -> MSF m a b -> MSF m a b+iPost b sf = MSF $ \_ -> return (b, sf)++next :: Monad m => b -> MSF m a b -> MSF m a b+next b sf = MSF $ \a -> do+  (b', sf') <- unMSF sf a+  return (b, next b' sf')+-- rather, once delay is tested:+-- next b sf = sf >>> delay b++-- * Alternative running functions++-- | Run an MSF fed from a list, discarding results. Useful when one needs to+-- combine effects and streams (i.e., for testing purposes).++-- TODO: This is not elementary, it can probably be built using other+-- construts. Move to a non-core module?+embed_ :: (Functor m, Monad m) => MSF m a () -> [a] -> m ()+embed_ msf as = void $ foldM (\sf a -> snd <$> unMSF sf a) msf as
+ src/Data/VectorSpace/Fractional.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE FlexibleInstances      #-}+{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE UndecidableInstances   #-}+{-# OPTIONS_GHC -fno-warn-orphans   #-}+module Data.VectorSpace.Fractional where++-- VectorSpace instances for Num/Fractional types. These sometimes clash with+-- user-defined instances.+-- (See https://github.com/ivanperez-keera/dunai/issues/11, where this+-- module used to be called Data.VectorSpace.Instances)++import Data.VectorSpace++instance Num a => RModule a where+    type Groundring a = a+    zeroVector     = 0+    a *^ x         = a * x+    negateVector x = -x+    x1 ^+^ x2      = x1 + x2+    x1 ^-^ x2      = x1 - x2++instance Fractional a => VectorSpace a where+    a ^/ x = a / x++instance Num a => InnerProductSpace a where+    x1 `dot` x2 = x1 * x2
− src/Data/VectorSpace/Instances.hs
@@ -1,22 +0,0 @@-{-# LANGUAGE FlexibleInstances      #-}-{-# LANGUAGE TypeFamilies           #-}-{-# LANGUAGE UndecidableInstances   #-}-module Data.VectorSpace.Instances where--import Data.VectorSpace---instance Num a => RModule a where-    type Groundring a = a-    zeroVector     = 0-    a *^ x         = a * x-    negateVector x = -x-    x1 ^+^ x2      = x1 + x2-    x1 ^-^ x2      = x1 - x2---instance Fractional a => VectorSpace a where-    a ^/ x = a / x--instance Num a => InnerProductSpace a where-    x1 `dot` x2 = x1 * x2
src/Data/VectorSpace/Specific.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE TypeFamilies           #-}+{-# LANGUAGE TypeFamilies         #-}+{-# OPTIONS_GHC -fno-warn-orphans #-} module Data.VectorSpace.Specific where  import Data.VectorSpace
src/Data/VectorSpace/Tuples.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE FlexibleInstances      #-} {-# LANGUAGE TypeFamilies           #-}+{-# OPTIONS_GHC -fno-warn-orphans   #-} module Data.VectorSpace.Tuples where  import Data.VectorSpace