[<<][meta][>>][..]
Mon Aug 15 18:16:12 CEST 2011

Is this SSM threading a Monad?

It's not the state monad, but...

The "purity" of Applicative (being parameterized by pure functions at
some point) doesn't seem to allow the kind of threading I want to
perform.  Let's try to cast it in a Monad instance.


_bind :: (     sa      -> (a, sa)) ->
         (a -> sb      -> (b, sb)) ->
         (     (sa,sb) -> (b, (sa,sb)))
         
_bind ma f = mb where         
  mb (sa, sb) = (b, (sa',sb')) where
    (a, sa') = ma sa
    (b, sb') = f a sb
    
_return :: a -> (() -> (a, ()))    
_return x = \_ -> (x, ())    
    

But (being a bit tired?) I can't seem to cast this into a Monad
instance for the data type:

data Signal a = forall s . Signal s (s -> (s, a))


It seems to be just wrapping issue.  Using the non-wrapped _bind I
managed to perform a composition:

ones = \s -> (1, s)
int  = \i s -> let o = i + s in (o,o) 
  
_run seq init = f init where
  f s = (v : f s') where
    (v, s') = seq s
   
*Main> take 10 $ _run (ones `_bind` int) (0,0)
[1,2,3,4,5,6,7,8,9,10]

*Main> take 10 $ _run ((ones `_bind` int) `_bind` int) ((0,0), 0)
[1,3,6,10,15,21,28,36,45,55]

This illustrates neatly why I really want to propagate initial states :)

Anyways, since Monad m => Applicative m I wonder why I can't write an
Applicative instance directly since it exists.

I found the following (ugly) implementation which includes initial
state passing.


--         in    state0   state       out state+
---------------------------------------------------  
__bind :: (     (sa,      sa      -> (a,  sa))) ->
          (a -> (sb,      sb      -> (b,  sb))) ->
          (     ((sa,sb), (sa,sb) -> (b,  (sa,sb))))
         
__bind (a0,ma) f = ((a0,b0),mb) where
  -- Get to b0 through a0 -> ma -> f since init state does not depend
  -- on the input.  There seems to be no other way to get at it.
  (a, _)  = ma a0
  (b0, _) = f a
  
  mb (sa, sb) = (b, (sa',sb')) where
    (a, sa') = ma sa
    (_, f')  = f a
    (b, sb') = f' sb

__return x = ((), \() -> (x, ()))

__ones = __return 1
__int  = \i -> (0, \s -> let o = i + s in (o,o))
  
__run (init,seq) = f init where
  f s = (v : f s') where
    (v, s') = seq s

This also works, but is a bit contrived, especially with that state
hiding on the inside of the __int.  Maybe this can be two monads, one
for state chaining, and one for passing the state around.

*Main Control.Monad> take 10 $ __run __ones
[1,1,1,1,1,1,1,1,1,1]

*Main Control.Monad> take 10 $ __run (__ones `__bind` __int)
[1,2,3,4,5,6,7,8,9,10]

*Main Control.Monad> take 10 $ __run ((__ones `__bind` __int) `__bind` __int)
[1,3,6,10,15,21,28,36,45,55]


However.. Trying to wrap this in Signal doesn't seem to work very
well.  I can't get it out of the wrapper!

instance Monad Signal where
  return = Signal . __return
  (>>=) (Signal ma) f = Signal $ __bind ma f' where
    f' a = case (f a) of
      (Signal mb) -> mb

This will give a generic, unknown type t to mb, not (s, s -> (v, s))
Is there a detour throug fmap and join?

Why won't unpacking work?  Maybe the "unpacking" is essential to monad
structure?

I think I need to stop.  Thoroughly confused now.

Hmm it seems I can define Applicative:

__ap mf ma =  mf `__bind` \f ->
              ma `__bind` \a ->
              __return $ f a

instance Functor Signal => Applicative Signal where
  pure = Signal . __return
  (<*>) (Signal f) (Signal a) = Signal (__ap f a)

Now I don't understand anything any more.  I thought I needed bind to
use processors of the form:

   m a -> (a -> m b) -> m b

But it seems that given that bind, it's not possible to create things
that could evaluate:

   m (a -> b) -> m a -> m b

How to create that m (a -> b) value?

That seems to be the catch.  Such values are not the same a (a -> m
b) because they cannot implement input-dependent state transitions.

Man this is confusing.



[Reply][About]
[<<][meta][>>][..]