{-# LANGUAGE Arrows #-}
{-# LANGUAGE Rank2Types #-}
module Data.MonadicStreamFunction.Util where
import Control.Arrow
import Control.Category
import Control.Monad
import Control.Monad.Base
import Data.Monoid
import Data.MonadicStreamFunction.Core
import Data.MonadicStreamFunction.Instances.ArrowChoice ()
import Data.VectorSpace
import Prelude hiding (id, (.))
import Control.Monad.Trans.MSF.State
type MStream m a = MSF m () a
type MSink m a = MSF m a ()
mapMaybeS :: Monad m => MSF m a b -> MSF m (Maybe a) (Maybe b)
mapMaybeS :: MSF m a b -> MSF m (Maybe a) (Maybe b)
mapMaybeS MSF m a b
msf = proc Maybe a
maybeA -> case Maybe a
maybeA of
Just a
a -> (b -> Maybe b) -> MSF m b (Maybe b)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr b -> Maybe b
forall a. a -> Maybe a
Just MSF m b (Maybe b) -> MSF m a b -> MSF m a (Maybe b)
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
<<< MSF m a b
msf -< a
a
Maybe a
Nothing -> MSF m (Maybe b) (Maybe b)
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< Maybe b
forall a. Maybe a
Nothing
withSideEffect :: Monad m => (a -> m b) -> MSF m a a
withSideEffect :: (a -> m b) -> MSF m a a
withSideEffect a -> m b
method = (MSF m a a
forall k (cat :: k -> k -> *) (a :: k). Category cat => cat a a
id MSF m a a -> MSF m a b -> MSF m a (a, b)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& (a -> m b) -> MSF m a b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> MSF m a b
arrM a -> m b
method) MSF m a (a, b) -> MSF m (a, b) a -> MSF m a a
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> ((a, b) -> a) -> MSF m (a, b) a
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (a, b) -> a
forall a b. (a, b) -> a
fst
withSideEffect_ :: Monad m => m b -> MSF m a a
withSideEffect_ :: m b -> MSF m a a
withSideEffect_ m b
method = (a -> m b) -> MSF m a a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> MSF m a a
withSideEffect ((a -> m b) -> MSF m a a) -> (a -> m b) -> MSF m a a
forall a b. (a -> b) -> a -> b
$ m b -> a -> m b
forall a b. a -> b -> a
const m b
method
iPre :: Monad m
=> a
-> MSF m a a
iPre :: a -> MSF m a a
iPre a
firsta = a -> MSF m (a, a) (a, a) -> MSF m a a
forall (m :: * -> *) c a b.
Monad m =>
c -> MSF m (a, c) (b, c) -> MSF m a b
feedback a
firsta (MSF m (a, a) (a, a) -> MSF m a a)
-> MSF m (a, a) (a, a) -> MSF m a a
forall a b. (a -> b) -> a -> b
$ ((a, a) -> (a, a)) -> MSF m (a, a) (a, a)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (a, a) -> (a, a)
forall b a. (b, a) -> (a, b)
swap
where swap :: (b, a) -> (a, b)
swap (b
a,a
b) = (a
b, b
a)
iPost :: Monad m => b -> MSF m a b -> MSF m a b
iPost :: b -> MSF m a b -> MSF m a b
iPost b
b MSF m a b
sf = MSF m a b
sf MSF m a b -> MSF m b b -> MSF m a b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (Maybe b -> MSF m (b, Maybe b) (b, Maybe b) -> MSF m b b
forall (m :: * -> *) c a b.
Monad m =>
c -> MSF m (a, c) (b, c) -> MSF m a b
feedback (b -> Maybe b
forall a. a -> Maybe a
Just b
b) (MSF m (b, Maybe b) (b, Maybe b) -> MSF m b b)
-> MSF m (b, Maybe b) (b, Maybe b) -> MSF m b b
forall a b. (a -> b) -> a -> b
$ ((b, Maybe b) -> (b, Maybe b)) -> MSF m (b, Maybe b) (b, Maybe b)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (((b, Maybe b) -> (b, Maybe b)) -> MSF m (b, Maybe b) (b, Maybe b))
-> ((b, Maybe b) -> (b, Maybe b))
-> MSF m (b, Maybe b) (b, Maybe b)
forall a b. (a -> b) -> a -> b
$ \(b
c, Maybe b
ac) -> case Maybe b
ac of
Maybe b
Nothing -> (b
c, Maybe b
forall a. Maybe a
Nothing)
Just b
b' -> (b
b', Maybe b
forall a. Maybe a
Nothing))
next :: Monad m => b -> MSF m a b -> MSF m a b
next :: b -> MSF m a b -> MSF m a b
next b
b MSF m a b
sf = MSF m a b
sf MSF m a b -> MSF m b b -> MSF m a b
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> b -> MSF m b b
forall (m :: * -> *) a. Monad m => a -> MSF m a a
iPre b
b
fifo :: Monad m => MSF m [a] (Maybe a)
fifo :: MSF m [a] (Maybe a)
fifo = [a] -> MSF m ([a], [a]) (Maybe a, [a]) -> MSF m [a] (Maybe a)
forall (m :: * -> *) c a b.
Monad m =>
c -> MSF m (a, c) (b, c) -> MSF m a b
feedback [] (MSF m ([a], [a]) (Maybe a, [a]) -> MSF m [a] (Maybe a))
-> MSF m ([a], [a]) (Maybe a, [a]) -> MSF m [a] (Maybe a)
forall a b. (a -> b) -> a -> b
$ proc ([a]
as, [a]
accum) -> do
let accum' :: [a]
accum' = [a]
accum [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++ [a]
as
MSF m (Maybe a, [a]) (Maybe a, [a])
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< case [a]
accum' of
[] -> (Maybe a
forall a. Maybe a
Nothing, [])
(a
a : [a]
as) -> (a -> Maybe a
forall a. a -> Maybe a
Just a
a , [a]
as)
count :: (Num n, Monad m) => MSF m a n
count :: MSF m a n
count = (a -> n) -> MSF m a n
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (n -> a -> n
forall a b. a -> b -> a
const n
1) MSF m a n -> MSF m n n -> MSF m a n
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> (n -> n -> n) -> n -> MSF m n n
forall (m :: * -> *) a s.
Monad m =>
(a -> s -> s) -> s -> MSF m a s
accumulateWith n -> n -> n
forall a. Num a => a -> a -> a
(+) n
0
sumS :: (VectorSpace v s, Monad m) => MSF m v v
sumS :: MSF m v v
sumS = v -> MSF m v v
forall v s (m :: * -> *).
(VectorSpace v s, Monad m) =>
v -> MSF m v v
sumFrom v
forall v a. VectorSpace v a => v
zeroVector
sumFrom :: (VectorSpace v s, Monad m) => v -> MSF m v v
sumFrom :: v -> MSF m v v
sumFrom = (v -> v -> v) -> v -> MSF m v v
forall (m :: * -> *) a s.
Monad m =>
(a -> s -> s) -> s -> MSF m a s
accumulateWith v -> v -> v
forall v a. VectorSpace v a => v -> v -> v
(^+^)
mappendS :: (Monoid n, Monad m) => MSF m n n
mappendS :: MSF m n n
mappendS = n -> MSF m n n
forall n (m :: * -> *). (Monoid n, Monad m) => n -> MSF m n n
mappendFrom n
forall a. Monoid a => a
mempty
{-# INLINE mappendS #-}
mappendFrom :: (Monoid n, Monad m) => n -> MSF m n n
mappendFrom :: n -> MSF m n n
mappendFrom = (n -> n -> n) -> n -> MSF m n n
forall (m :: * -> *) a s.
Monad m =>
(a -> s -> s) -> s -> MSF m a s
accumulateWith n -> n -> n
forall a. Monoid a => a -> a -> a
mappend
accumulateWith :: Monad m => (a -> s -> s) -> s -> MSF m a s
accumulateWith :: (a -> s -> s) -> s -> MSF m a s
accumulateWith a -> s -> s
f s
s0 = s -> MSF m (a, s) (s, s) -> MSF m a s
forall (m :: * -> *) c a b.
Monad m =>
c -> MSF m (a, c) (b, c) -> MSF m a b
feedback s
s0 (MSF m (a, s) (s, s) -> MSF m a s)
-> MSF m (a, s) (s, s) -> MSF m a s
forall a b. (a -> b) -> a -> b
$ ((a, s) -> (s, s)) -> MSF m (a, s) (s, s)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (a, s) -> (s, s)
g
where
g :: (a, s) -> (s, s)
g (a
a, s
s) = let s' :: s
s' = a -> s -> s
f a
a s
s in (s
s', s
s')
mealy :: Monad m => (a -> s -> (b, s)) -> s -> MSF m a b
mealy :: (a -> s -> (b, s)) -> s -> MSF m a b
mealy a -> s -> (b, s)
f s
s0 = s -> MSF m (a, s) (b, s) -> MSF m a b
forall (m :: * -> *) c a b.
Monad m =>
c -> MSF m (a, c) (b, c) -> MSF m a b
feedback s
s0 (MSF m (a, s) (b, s) -> MSF m a b)
-> MSF m (a, s) (b, s) -> MSF m a b
forall a b. (a -> b) -> a -> b
$ ((a, s) -> (b, s)) -> MSF m (a, s) (b, s)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (((a, s) -> (b, s)) -> MSF m (a, s) (b, s))
-> ((a, s) -> (b, s)) -> MSF m (a, s) (b, s)
forall a b. (a -> b) -> a -> b
$ (a -> s -> (b, s)) -> (a, s) -> (b, s)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry a -> s -> (b, s)
f
unfold :: Monad m => (a -> (b, a)) -> a -> MSF m () b
unfold :: (a -> (b, a)) -> a -> MSF m () b
unfold a -> (b, a)
f a
a = a -> MSF m ((), a) (b, a) -> MSF m () b
forall (m :: * -> *) c a b.
Monad m =>
c -> MSF m (a, c) (b, c) -> MSF m a b
feedback a
a ((((), a) -> (b, a)) -> MSF m ((), a) (b, a)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (((), a) -> a
forall a b. (a, b) -> b
snd (((), a) -> a) -> (a -> (b, a)) -> ((), a) -> (b, a)
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> a -> (b, a)
f))
repeatedly :: Monad m => (a -> a) -> a -> MSF m () a
repeatedly :: (a -> a) -> a -> MSF m () a
repeatedly a -> a
f = (a -> (a, a)) -> a -> MSF m () a
forall (m :: * -> *) a b.
Monad m =>
(a -> (b, a)) -> a -> MSF m () b
unfold ((a -> (a, a)) -> a -> MSF m () a)
-> (a -> (a, a)) -> a -> MSF m () a
forall a b. (a -> b) -> a -> b
$ a -> a
f (a -> a) -> (a -> (a, a)) -> a -> (a, a)
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> a -> (a, a)
forall b. b -> (b, b)
dup
where
dup :: b -> (b, b)
dup b
a = (b
a, b
a)
trace :: Show a => String -> MSF IO a a
trace :: String -> MSF IO a a
trace = (String -> IO ()) -> String -> MSF IO a a
forall (m :: * -> *) a.
(Monad m, Show a) =>
(String -> m ()) -> String -> MSF m a a
traceWith String -> IO ()
putStrLn
traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a
traceWith :: (String -> m ()) -> String -> MSF m a a
traceWith String -> m ()
method String
msg =
(a -> m ()) -> MSF m a a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> MSF m a a
withSideEffect (String -> m ()
method (String -> m ()) -> (a -> String) -> a -> m ()
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (String
msg String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (a -> String) -> a -> String
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> String
forall a. Show a => a -> String
show)
traceWhen :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MSF m a a
traceWhen :: (a -> Bool) -> (String -> m ()) -> String -> MSF m a a
traceWhen a -> Bool
cond String -> m ()
method String
msg = (a -> m ()) -> MSF m a a
forall (m :: * -> *) a b. Monad m => (a -> m b) -> MSF m a a
withSideEffect ((a -> m ()) -> MSF m a a) -> (a -> m ()) -> MSF m a a
forall a b. (a -> b) -> a -> b
$ \a
a ->
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (a -> Bool
cond a
a) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
method (String -> m ()) -> String -> m ()
forall a b. (a -> b) -> a -> b
$ String
msg String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
a
pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a
pauseOn :: (a -> Bool) -> String -> MSF IO a a
pauseOn a -> Bool
cond = (a -> Bool) -> (String -> IO ()) -> String -> MSF IO a a
forall (m :: * -> *) a.
(Monad m, Show a) =>
(a -> Bool) -> (String -> m ()) -> String -> MSF m a a
traceWhen a -> Bool
cond ((String -> IO ()) -> String -> MSF IO a a)
-> (String -> IO ()) -> String -> MSF IO a a
forall a b. (a -> b) -> a -> b
$ \String
s -> String -> IO ()
forall a. Show a => a -> IO ()
print String
s IO () -> IO String -> IO String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO String
getLine IO String -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()