{-# LANGUAGE Arrows #-}
{-# LANGUAGE RecordWildCards #-}
module LiveCoding.Cell.Util where
import Control.Arrow
import Control.Monad.IO.Class
import Data.Data (Data)
import Data.Functor (void)
import Data.Maybe
import Data.Sequence hiding (take)
import qualified Data.Sequence as Sequence
import Data.Time.Clock
import LiveCoding.Cell
import LiveCoding.Cell.Feedback
sumFrom :: Monad m => Integer -> Cell m Integer Integer
sumFrom :: Integer -> Cell m Integer Integer
sumFrom Integer
n0 = Integer
-> Cell m (Integer, Integer) (Integer, Integer)
-> Cell m Integer Integer
forall (m :: * -> *) s a b.
(Monad m, Data s) =>
s -> Cell m (a, s) (b, s) -> Cell m a b
feedback Integer
n0 (Cell m (Integer, Integer) (Integer, Integer)
-> Cell m Integer Integer)
-> Cell m (Integer, Integer) (Integer, Integer)
-> Cell m Integer Integer
forall a b. (a -> b) -> a -> b
$ proc (Integer
n, Integer
acc) -> Cell m (Integer, Integer) (Integer, Integer)
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< (Integer
acc, Integer
acc Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
n)
count :: Monad m => Cell m a Integer
count :: Cell m a Integer
count = (a -> Integer) -> Cell m a Integer
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (Integer -> a -> Integer
forall a b. a -> b -> a
const Integer
1) Cell m a Integer -> Cell m Integer Integer -> Cell m a Integer
forall k (cat :: k -> k -> *) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Cell m Integer Integer
forall (m :: * -> *) a. (Monad m, Num a, Data a) => Cell m a a
sumC
foldC :: (Data b, Monad m) => (a -> b -> b) -> b -> Cell m a b
foldC :: (a -> b -> b) -> b -> Cell m a b
foldC a -> b -> b
step b
cellState = Cell :: forall (m :: * -> *) a b s.
Data s =>
s -> (s -> a -> m (b, s)) -> Cell m a b
Cell { b
b -> a -> m (b, b)
forall (m :: * -> *). Monad m => b -> a -> m (b, b)
cellStep :: b -> a -> m (b, b)
cellState :: b
cellStep :: forall (m :: * -> *). Monad m => b -> a -> m (b, b)
cellState :: b
.. }
where
cellStep :: b -> a -> m (b, b)
cellStep b
b a
a = let b' :: b
b' = a -> b -> b
step a
a b
b in (b, b) -> m (b, b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b
b, b
b')
foldC' :: (Data b, Monad m) => (a -> b -> b) -> b -> Cell m a b
foldC' :: (a -> b -> b) -> b -> Cell m a b
foldC' a -> b -> b
step b
cellState = Cell :: forall (m :: * -> *) a b s.
Data s =>
s -> (s -> a -> m (b, s)) -> Cell m a b
Cell { b
b -> a -> m (b, b)
forall (m :: * -> *). Monad m => b -> a -> m (b, b)
cellStep :: forall (m :: * -> *). Monad m => b -> a -> m (b, b)
cellState :: b
cellStep :: b -> a -> m (b, b)
cellState :: b
.. }
where
cellStep :: b -> a -> m (b, b)
cellStep b
b a
a = let b' :: b
b' = a -> b -> b
step a
a b
b in (b, b) -> m (b, b)
forall (m :: * -> *) a. Monad m => a -> m a
return (b
b', b
b')
keep :: (Data a, Monad m) => a -> Cell m (Maybe a) a
keep :: a -> Cell m (Maybe a) a
keep a
a = a -> Cell m (Maybe a, a) (a, a) -> Cell m (Maybe a) a
forall (m :: * -> *) s a b.
(Monad m, Data s) =>
s -> Cell m (a, s) (b, s) -> Cell m a b
feedback a
a (Cell m (Maybe a, a) (a, a) -> Cell m (Maybe a) a)
-> Cell m (Maybe a, a) (a, a) -> Cell m (Maybe a) a
forall a b. (a -> b) -> a -> b
$ proc (Maybe a
ma, a
aOld) -> do
let aNew :: a
aNew = a -> Maybe a -> a
forall a. a -> Maybe a -> a
fromMaybe a
aOld Maybe a
ma
Cell m (a, a) (a, a)
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< (a
aNew, a
aNew)
keepJust
:: (Monad m, Data a)
=> Cell m (Maybe a) (Maybe a)
keepJust :: Cell m (Maybe a) (Maybe a)
keepJust = Maybe a
-> Cell m (Maybe a, Maybe a) (Maybe a, Maybe a)
-> Cell m (Maybe a) (Maybe a)
forall (m :: * -> *) s a b.
(Monad m, Data s) =>
s -> Cell m (a, s) (b, s) -> Cell m a b
feedback Maybe a
forall a. Maybe a
Nothing (Cell m (Maybe a, Maybe a) (Maybe a, Maybe a)
-> Cell m (Maybe a) (Maybe a))
-> Cell m (Maybe a, Maybe a) (Maybe a, Maybe a)
-> Cell m (Maybe a) (Maybe a)
forall a b. (a -> b) -> a -> b
$ ((Maybe a, Maybe a) -> (Maybe a, Maybe a))
-> Cell m (Maybe a, Maybe a) (Maybe a, Maybe a)
forall (a :: * -> * -> *) b c. Arrow a => (b -> c) -> a b c
arr (Maybe a, Maybe a) -> (Maybe a, Maybe a)
forall a. (Maybe a, Maybe a) -> (Maybe a, Maybe a)
keep
where
keep :: (Maybe a, Maybe a) -> (Maybe a, Maybe a)
keep (Maybe a
Nothing, Maybe a
Nothing) = (Maybe a
forall a. Maybe a
Nothing, Maybe a
forall a. Maybe a
Nothing)
keep (Maybe a
_, Just a
a) = (a -> Maybe a
forall a. a -> Maybe a
Just a
a, a -> Maybe a
forall a. a -> Maybe a
Just a
a)
keep (Just a
a, Maybe a
Nothing) = (a -> Maybe a
forall a. a -> Maybe a
Just a
a, a -> Maybe a
forall a. a -> Maybe a
Just a
a)
boundedFIFO :: (Data a, Monad m) => Int -> Cell m (Maybe a) (Seq a)
boundedFIFO :: Int -> Cell m (Maybe a) (Seq a)
boundedFIFO Int
n = (Maybe a -> Seq a -> Seq a) -> Seq a -> Cell m (Maybe a) (Seq a)
forall b (m :: * -> *) a.
(Data b, Monad m) =>
(a -> b -> b) -> b -> Cell m a b
foldC' Maybe a -> Seq a -> Seq a
forall a. Maybe a -> Seq a -> Seq a
step Seq a
forall a. Seq a
empty
where
step :: Maybe a -> Seq a -> Seq a
step Maybe a
Nothing Seq a
as = Seq a
as
step (Just a
a) Seq a
as = Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Sequence.take Int
n (Seq a -> Seq a) -> Seq a -> Seq a
forall a b. (a -> b) -> a -> b
$ a
a a -> Seq a -> Seq a
forall a. a -> Seq a -> Seq a
<| Seq a
as
edge :: Monad m => Cell m Bool Bool
edge :: Cell m Bool Bool
edge = proc Bool
b -> do
Bool
bLast <- Bool -> Cell m Bool Bool
forall s (m :: * -> *). (Data s, Monad m) => s -> Cell m s s
delay Bool
False -< Bool
b
Cell m Bool Bool
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< Bool
b Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
bLast
printTime :: MonadIO m => String -> m ()
printTime :: String -> m ()
printTime String
msg = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
putStrLn (String -> IO ()) -> (UTCTime -> String) -> UTCTime -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
8 String
msg String -> String -> String
forall a. [a] -> [a] -> [a]
++) (String -> String) -> (UTCTime -> String) -> UTCTime -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UTCTime -> String
forall a. Show a => a -> String
show (UTCTime -> IO ()) -> IO UTCTime -> IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< IO UTCTime
getCurrentTime
printTimeC :: MonadIO m => String -> Cell m () ()
printTimeC :: String -> Cell m () ()
printTimeC String
msg = m () -> Cell m () ()
forall (m :: * -> *) b a. m b -> Cell m a b
constM (m () -> Cell m () ()) -> m () -> Cell m () ()
forall a b. (a -> b) -> a -> b
$ String -> m ()
forall (m :: * -> *). MonadIO m => String -> m ()
printTime String
msg
data BufferCommand a
= Push a
| Pop
maybePush :: Maybe a -> [BufferCommand a]
maybePush :: Maybe a -> [BufferCommand a]
maybePush = (a -> BufferCommand a
forall a. a -> BufferCommand a
Push (a -> BufferCommand a) -> [a] -> [BufferCommand a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) ([a] -> [BufferCommand a])
-> (Maybe a -> [a]) -> Maybe a -> [BufferCommand a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> [a]
forall a. Maybe a -> [a]
maybeToList
maybePop :: Maybe a -> [BufferCommand b]
maybePop :: Maybe a -> [BufferCommand b]
maybePop = (BufferCommand b -> a -> BufferCommand b
forall a b. a -> b -> a
const BufferCommand b
forall a. BufferCommand a
Pop (a -> BufferCommand b) -> [a] -> [BufferCommand b]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) ([a] -> [BufferCommand b])
-> (Maybe a -> [a]) -> Maybe a -> [BufferCommand b]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe a -> [a]
forall a. Maybe a -> [a]
maybeToList
buffer :: (Monad m, Data a) => Cell m [BufferCommand a] (Maybe a)
buffer :: Cell m [BufferCommand a] (Maybe a)
buffer = Cell :: forall (m :: * -> *) a b s.
Data s =>
s -> (s -> a -> m (b, s)) -> Cell m a b
Cell { Seq a
Seq a -> [BufferCommand a] -> m (Maybe a, Seq a)
forall a. Seq a
forall (m :: * -> *) a.
Monad m =>
Seq a -> [BufferCommand a] -> m (Maybe a, Seq a)
cellStep :: forall (m :: * -> *) a.
Monad m =>
Seq a -> [BufferCommand a] -> m (Maybe a, Seq a)
cellState :: forall a. Seq a
cellStep :: Seq a -> [BufferCommand a] -> m (Maybe a, Seq a)
cellState :: Seq a
.. }
where
cellState :: Seq a
cellState = Seq a
forall a. Seq a
empty
cellStep :: Seq a -> [BufferCommand a] -> m (Maybe a, Seq a)
cellStep Seq a
as [BufferCommand a]
commands = (Maybe a, Seq a) -> m (Maybe a, Seq a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Seq a -> Maybe a
forall a. Seq a -> Maybe a
currentHead Seq a
as, Seq a -> [BufferCommand a] -> Seq a
forall a. Seq a -> [BufferCommand a] -> Seq a
nextBuffer Seq a
as [BufferCommand a]
commands)
currentHead :: Seq a -> Maybe a
currentHead Seq a
as = case Seq a -> ViewL a
forall a. Seq a -> ViewL a
viewl Seq a
as of
ViewL a
EmptyL -> Maybe a
forall a. Maybe a
Nothing
a
a :< Seq a
as' -> a -> Maybe a
forall a. a -> Maybe a
Just a
a
nextBuffer :: Seq a -> [BufferCommand a] -> Seq a
nextBuffer Seq a
as [] = Seq a
as
nextBuffer Seq a
as (Push a
a : [BufferCommand a]
commands) = Seq a -> [BufferCommand a] -> Seq a
nextBuffer (Seq a
as Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
|> a
a) [BufferCommand a]
commands
nextBuffer Seq a
as (BufferCommand a
Pop : [BufferCommand a]
commands) = Seq a -> [BufferCommand a] -> Seq a
nextBuffer (Int -> Seq a -> Seq a
forall a. Int -> Seq a -> Seq a
Sequence.drop Int
1 Seq a
as) [BufferCommand a]
commands
buffered
:: (Monad m, Data a)
=> Cell m (Maybe a) (Maybe b)
-> Cell m (Maybe a) (Maybe b)
buffered :: Cell m (Maybe a) (Maybe b) -> Cell m (Maybe a) (Maybe b)
buffered Cell m (Maybe a) (Maybe b)
cell = Maybe ()
-> Cell m (Maybe a, Maybe ()) (Maybe b, Maybe ())
-> Cell m (Maybe a) (Maybe b)
forall (m :: * -> *) s a b.
(Monad m, Data s) =>
s -> Cell m (a, s) (b, s) -> Cell m a b
feedback Maybe ()
forall a. Maybe a
Nothing (Cell m (Maybe a, Maybe ()) (Maybe b, Maybe ())
-> Cell m (Maybe a) (Maybe b))
-> Cell m (Maybe a, Maybe ()) (Maybe b, Maybe ())
-> Cell m (Maybe a) (Maybe b)
forall a b. (a -> b) -> a -> b
$ proc (Maybe a
aMaybe, Maybe ()
ticked) -> do
Maybe a
aMaybe' <- Cell m [BufferCommand a] (Maybe a)
forall (m :: * -> *) a.
(Monad m, Data a) =>
Cell m [BufferCommand a] (Maybe a)
buffer -< Maybe () -> [BufferCommand a]
forall a b. Maybe a -> [BufferCommand b]
maybePop Maybe ()
ticked [BufferCommand a] -> [BufferCommand a] -> [BufferCommand a]
forall a. [a] -> [a] -> [a]
++ Maybe a -> [BufferCommand a]
forall a. Maybe a -> [BufferCommand a]
maybePush Maybe a
aMaybe
Maybe b
bMaybe' <- Cell m (Maybe a) (Maybe b)
cell -< Maybe a
aMaybe'
Cell m (Maybe b, Maybe ()) (Maybe b, Maybe ())
forall (a :: * -> * -> *) b. Arrow a => a b b
returnA -< (Maybe b
bMaybe', Maybe b -> Maybe ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void Maybe b
bMaybe')