Sat Aug 27 16:00:18 CEST 2011

Connecting sharing monad to SigOp

So it seems to work, after some struggle.  Now the tuple problem.
What does it mean to do something like this, creating two monadic
values (m,m) instead of m(,)  ?

  f2 a b = do  
    aa <- a `imul` a
    bb <- b `imul` b
    (aa `iadd` bb, aa `isub` bb)

The inferred type sheds some light:

  f2 :: (DSPM r m1, DSPM r ((,) (m (r Tint))), DSPM r m) =>
     r Tint -> r Tint -> (m (r Tint), m1 (r Tint))

The problem is that the tuple operator does not produce a single
monadic value.  I.e. it doesn't "live in the monad".

So how to I shoehorn functions that look like a -> m b into
(s,i)->(s,o) ?

Wait a minute.  What about this:

  f3 a b = do  
    aa <- a `imul` a
    bb <- b `imul` b
    ap <- aa `iadd` bb
    am <- aa `isub` bb
    return $ (ap, am)

At least this has a proper type:

  f3 :: DSPM r m => r Tint -> r Tint -> m (r Tint, r Tint)

Is it possible to "evaluate" the monad into a simple function so it
can still serve as a pure update (s,i) -> (s,o) ?

Just thinking about it: of coruse there should be no problem to
convert the CPS computation back into a pure function.  It *is* a pure
function.  But this can only be done if the monad instance is known.

Hmm... maybe that's not really true.  The point is to build one huge
function *inside the monad* such that compositions made by SigOp can
use sharing.  That's what was wrong in the other approach.

So I really need to be able to compose (s,i) -> m (s,o) for some Monad
m which is part of the language in which the siso's are written.

Is that a problem?

No it was surprisingly straightforward.

The only difference is that I don't have the num class for examples.
Or maybe I do?  Ok, I just define everything in terms of the monadic
DSPM language, that's what it's made for.  Here we are:

  int = opr $ \(s, i) -> do { o <- i `iadd` s; return (o, o) }

*Main> :t int
  :: (SigState (r Tint), DSPM r m, Num (r Tint)) =>
     SigOpM m (r Tint) (r Tint)

*Main> :t int . int . int
int . int . int
  :: (SigState (r Tint), DSPM r m, Num (r Tint)) =>
     SigOpM m (r Tint) (r Tint)

Looks like it's working.  Now, how to convert to expression?  Need to
take a step back.  Damn it's easy to abstract away common sense!

I'm having trouble to get this to behave.  Somehow the monad types are
not identified when I insert such an ilit in an expression

  ilit  :: Tint -> (r Tint)

this was the previous definition, but it is inconvenient as it has to
be unpacked.

  ilit  :: Tint -> m (r Tint)

Pff.. I'm doing shotgun programming.  Maybe the initial value should
be monadic?  Probably not a good idea since that requires also binding
when composing.  Anyways.  Try later..

What should work with this approach though is stream unrolling!