module Filter.MonadFix where

import qualified Filter.Graph as Graph
import qualified Filter.Fix   as FFix

import Filter.Fix (Channel(Channel), ChannelId)

import Control.Monad.State (StateT, evalStateT, get, modify, lift)
import Control.Monad.Writer (Writer, execWriter, tell)

If you find 'Filter.Fix.T' still inconvenient,
and if you don't care about portability,
you can also use the following monad with the @mdo@ notation.

> mdo
>   v <- a(u + dw)
>   w <- b(v + ey)
>   y <- c w


type T filter t a v x  =  StateT ChannelId (Writer [Channel filter t a v]) x

makeChannel ::
   [(ChannelId, filter t a v)] ->
   T filter t a v ChannelId
makeChannel inputs =
   do n <- get
      modify succ
      lift $ tell [Channel n inputs]
      return n

run :: T filter t a v x -> [Channel filter t a v]
run m = execWriter (evalStateT m 0)

toGraph :: T filter t a v x -> Graph.T filter Int t a v
toGraph =
   Graph.fromList . map (\(Channel n inputs) -> (n, inputs)) . run