signals-0.0.0.1: Frontend/Stream.hs
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ConstraintKinds #-}
module Frontend.Stream where
import Core (CMD, newRef, getRef, setRef)
import Control.Applicative
import Control.Monad
import Control.Monad.Operational
import Data.Typeable (Typeable)
import Prelude (($))
import qualified Prelude as P
--------------------------------------------------------------------------------
-- * Streams
--------------------------------------------------------------------------------
-- | ...
data Stream exp a
where
Stream :: Program (CMD exp) (Program (CMD exp) a) -> Stream exp a
-- | ...
type Str exp a = Stream exp (exp a)
--------------------------------------------------------------------------------
-- ** Instances
deriving instance Typeable Stream
--------------------------------------------------------------------------------
-- * User Interface
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- ** constructors
-- | creates a stream from a program
stream :: Program (CMD exp) (Program (CMD exp) (exp a)) -> Str exp a
stream = Stream
--------------------------------------------------------------------------------
-- ** Combinatorial functions
-- | creates and infinite stream by repeating @a@
repeat :: exp a -> Str exp a
repeat a = Stream $ return $ return a
-- | point-wise transform each value produced with @f@
map :: (exp a -> exp b) -> Str exp a -> Str exp b
map f (Stream init) = Stream $ fmap (fmap f) init
-- | joined two streams using @f@ to merge produced elements
zipWith :: (exp a -> exp b -> exp c)
-> Str exp a -> Str exp b -> Str exp c
zipWith f (Stream init1) (Stream init2) = Stream $ do
next1 <- init1
next2 <- init2
return $ do
a <- next1
b <- next2
return $ f a b
--------------------------------------------------------------------------------
-- ** Sequential functions
-- | preappend @a@ to input stream
delay :: Typeable a => exp a -> Str exp a -> Str exp a
delay a (Stream init) = Stream $ do
next <- init
r <- newRef a
return $ do
o <- getRef r
v <- next
setRef r v
return o
--------------------------------------------------------------------------------
-- ** Run Functions
run :: Stream exp a -> Program (CMD exp) a
run (Stream init) = join init