signals-0.0.0.1: Frontend/SignalObsv.hs
{-# LANGUAGE GADTs #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Frontend.SignalObsv where
import Interpretation
import Frontend.Signal (Signal(..), Sig(..), StructT(..), Empty, Struct, TStruct)
import Frontend.Stream (Stream(..), Str(..))
import Control.Applicative hiding (Const)
import Data.Dynamic
import Data.Proxy
import Data.Reify
import Data.Typeable
--------------------------------------------------------------------------------
-- * Graph representation of Signals
--------------------------------------------------------------------------------
data TSignal exp r
where
-- ^ Signal functions
TLambda :: r -> r -> TSignal exp r
TVar :: (Typeable a, Typeable exp)
=> TStruct exp a
-> TSignal exp r
-- ^ Signal
TConst :: (Typeable a, Typeable exp)
=> Stream exp (exp a) -> TSignal exp r
TLift :: (Typeable a, Typeable b, Typeable exp)
=> (Stream exp (exp a) -> Stream exp (exp b))
-> r -> TSignal exp r
TMap :: (Typeable a, Typeable b, Typeable exp)
=> TStruct exp a -> TStruct exp b
-> (Struct exp a -> Struct exp b)
-> r -> TSignal exp r
TZip :: (Typeable a, Typeable b)
=> TStruct exp a
-> TStruct exp b
-> r -> r -> TSignal exp r
TFst :: (Typeable a, Typeable b)
=> TStruct exp (a, b)
-> r -> TSignal exp r
TSnd :: (Typeable a, Typeable b)
=> TStruct exp (a, b)
-> r -> TSignal exp r
TDelay :: (Typeable a, Typeable exp) => exp a -> r -> TSignal exp r
-- ^ Buffers
TBuff :: (Typeable a, Typeable exp)
=> proxy (exp a)
-> r -> TSignal exp r
deriving (Typeable)
type Node e = TSignal e Unique
--------------------------------------------------------------------------------
-- ** Helper functions
edges :: TSignal e a -> [a]
edges node =
case node of
TLambda x y -> [x, y]
TVar _ -> []
TConst _ -> []
TLift _ x -> [x]
TMap _ _ _ x -> [x]
TZip _ _ x y -> [x, y]
TFst _ x -> [x]
TSnd _ x -> [x]
TDelay _ x -> [x]
--------------------------------------------------------------------------------
-- ** MuRef instances for signals
instance (Typeable exp) => MuRef (Signal exp a)
where
type DeRef (Signal exp a) = TSignal exp
mapDeRef f node = case node of
(Const sf) -> pure $ TConst sf
(Lift sf s) -> TLift sf <$> f s
(Map sf s) -> TMap (rep s) (rep (undefined :: Struct exp a)) sf <$> f s
(Zip s u) -> TZip (rep s) (rep u) <$> f s <*> f u
(Fst s) -> TFst (rep s) <$> f s
(Snd s) -> TSnd (rep s) <$> f s
(Delay a s) -> TDelay a <$> f s
(SVar _) -> pure $ TVar (rep (undefined :: Struct exp a))
instance ( Typeable a, Typeable b, Typeable exp
, StructT a, DomainT a ~ exp
) =>
MuRef (Signal exp a -> Signal exp b)
where
type DeRef (Signal exp a -> Signal exp b) = TSignal exp
mapDeRef f sf =
let (v, sg) = let a = SVar (toDyn sf) in (a, sf a)
in TLambda <$> f v <*> f sg
--------------------------------------------------------------------------------
-- ** MuRef instances for sig
instance (Typeable exp) => MuRef (Sig exp a)
where
type DeRef (Sig exp a) = TSignal exp
mapDeRef f node = mapDeRef f (unSig node)
instance (Typeable a, Typeable b, Typeable exp) =>
MuRef (Sig exp a -> Sig exp b)
where
type DeRef (Sig exp a -> Sig exp b) = TSignal exp
mapDeRef f sf = mapDeRef f (unSig . sf . Sig)
--------------------------------------------------------------------------------
-- * Testing
--------------------------------------------------------------------------------
instance Show a => Show (TSignal exp a) where
show node = case node of
(TLambda i b) -> "lam. " ++ show i ++ " " ++ show b
(TVar _) -> "var. "
(TConst _) -> "const. "
(TLift _ s) -> "lift. " ++ show s
(TMap _ _ _ s) -> "map. " ++ show s
(TZip _ _ s u) -> "zip. " ++ show s ++ " " ++ show u
(TFst _ s) -> "fst. " ++ show s
(TSnd _ s) -> "snd. " ++ show s
(TDelay _ s) -> "delay. " ++ show s
(TBuff _ r) -> "dbuff ." ++ show r