{-# LANGUAGE Arrows #-}
{-# LANGUAGE CPP #-}
module Data.MonadicStreamFunction.Util where
import Control.Arrow (arr, returnA, (&&&), (<<<), (>>>))
import Control.Category (id, (.))
import Control.Monad (when)
import Data.VectorSpace (VectorSpace, zeroVector, (^+^))
import Prelude hiding (id, (.))
#if !MIN_VERSION_base(4,8,0)
import Data.Monoid (Monoid, mempty, mappend)
#endif
import Data.MonadicStreamFunction.Core (MSF, arrM, feedback)
import Data.MonadicStreamFunction.Instances.ArrowChoice ()
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 :: forall (m :: * -> *) a b.
Monad m =>
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 b c. (b -> c) -> MSF m b c
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 :: forall (m :: * -> *) a b. Monad m => (a -> m b) -> MSF m a a
withSideEffect a -> m b
method = (MSF m a a
forall a. 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 b c c'. MSF m b c -> MSF m b c' -> MSF m b (c, c')
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 b c. (b -> c) -> MSF m b c
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_ :: forall (m :: * -> *) b a. Monad m => 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 :: forall (m :: * -> *) a. Monad m => 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 b c. (b -> c) -> MSF m b c
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 :: forall (m :: * -> *) b a. Monad m => 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 b c. (b -> c) -> MSF m b c
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 :: forall (m :: * -> *) b a. Monad m => 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 :: forall (m :: * -> *) a. Monad m => 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 [] ((([a], [a]) -> (Maybe a, [a])) -> MSF m ([a], [a]) (Maybe a, [a])
forall b c. (b -> c) -> MSF m b c
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr ([a] -> (Maybe a, [a])
forall x. [x] -> (Maybe x, [x])
safeSnoc ([a] -> (Maybe a, [a]))
-> (([a], [a]) -> [a]) -> ([a], [a]) -> (Maybe a, [a])
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ([a] -> [a] -> [a]) -> ([a], [a]) -> [a]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [a] -> [a] -> [a]
forall x. [x] -> [x] -> [x]
fifoAppend))
where
fifoAppend :: [x] -> [x] -> [x]
fifoAppend :: forall x. [x] -> [x] -> [x]
fifoAppend [x]
as [x]
accum = [x]
accum [x] -> [x] -> [x]
forall x. [x] -> [x] -> [x]
++ [x]
as
safeSnoc :: [x] -> (Maybe x, [x])
safeSnoc :: forall x. [x] -> (Maybe x, [x])
safeSnoc [] = (Maybe x
forall a. Maybe a
Nothing, [])
safeSnoc (x
x:[x]
xs) = (x -> Maybe x
forall a. a -> Maybe a
Just x
x, [x]
xs)
count :: (Num n, Monad m) => MSF m a n
count :: forall n (m :: * -> *) a. (Num n, Monad m) => MSF m a n
count = (a -> n) -> MSF m a n
forall b c. (b -> c) -> MSF m b c
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 :: forall v s (m :: * -> *). (VectorSpace v s, Monad m) => 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 :: forall v s (m :: * -> *).
(VectorSpace v s, Monad m) =>
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 :: forall n (m :: * -> *). (Monoid n, Monad m) => 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 :: forall n (m :: * -> *). (Monoid n, Monad m) => 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 :: forall (m :: * -> *) a s.
Monad m =>
(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 b c. (b -> c) -> MSF m b c
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 :: forall (m :: * -> *) a s b.
Monad m =>
(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 b c. (b -> c) -> MSF m b c
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 :: forall (m :: * -> *) a b.
Monad m =>
(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 b c. (b -> c) -> MSF m b c
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 :: forall (m :: * -> *) a. Monad m => (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 :: forall a. Show a => 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 :: forall (m :: * -> *) a.
(Monad m, Show a) =>
(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 b c a. (b -> c) -> (a -> b) -> a -> c
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 x. [x] -> [x] -> [x]
++) (String -> String) -> (a -> String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
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 :: forall (m :: * -> *) a.
(Monad m, Show a) =>
(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 x. [x] -> [x] -> [x]
++ a -> String
forall a. Show a => a -> String
show a
a
pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a
pauseOn :: forall a. Show a => (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 a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> IO String
getLine IO String -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()