Mon Aug 15 17:16:31 CEST 2011

Tying the knot with Applicative

The following type doesn't seem to work because state can depend on
the input to the function:

currySSM :: ((s,i) -> (s,o)) ->
            (s -> (s, i -> o))

Is there a way to do this with

currySSM :: ((s,i) -> s) ->
            ((s,i) -> o) ->
            (s -> (s, i -> o))

Seems to have the same problem.  The only thing that works is to take
the input out of the tuple:

currySSM :: ((s,i) -> (s,o)) ->
            (s -> i -> (s, o))

currySSM ssm = f where
  f s i = (s', o) where
    (s', o) = ssm (s, i)

What about requiring the state of a function to be of the form (s -> i
-> (s, o)) ?   Hmm.. seems like another ill-informed idea..

The secret really has to be in signalApp.  I'm doing something that
fundamentally prevents Applicative to work.

Maybe try to answer some more generic questions.

  - Look at the type of <*>.  This seems to have "naked" functions and
    values.  These need to be parameters of some type, so where do
    they appear?  As inputs, outputs, middles?

    <*> :: Applicative a => a (x -> y) -> a x -> a y

In some sense the function is definitely some output of something.
The problem is that I want to depend on what goes into a function like
that to make state updates.  This seems to be not allowed.

The only way I can see this work is if somehow an i->o function can
parameterize a state update.  Meaning *not* the input, but the
function itself.  Can the state be a function?

  (s1        -> (s1,      i))       ->
  ((i -> s2) -> (i -> s2, i -> o))  ->
  ((s1,s2)   -> ((s1,s2), o)

The thing is that in app the input is available.  Can we use this to
chain it?

The following compiles and seems to be correct from inspection.

_app :: (s1        -> (i -> s1,  i -> o))  ->  -- fx
        (s2        -> (s2,       i))       ->  -- ix
        ((s1, s2)  -> ((s1, s2), o))           -- ox
_app fx ix = ox where
  ox (s1, s2) = ((s1', s2'), o) where
    (is1', f) = fx s1
    (s2',  i) = ix s2
    s1' = is1' i
    o   = f i

But the types are iregular and don't fit (s -> (s,v)).  Can they be
cast into a different form?

_app :: ((i -> s1)      -> (i -> s1,       i -> o))  ->  -- fx
        (s2             -> (s2,            i))       ->  -- ix
        ((i -> s1, s2)  -> ((i -> s1, s2), o))           -- ox
_app fx ix = ox where
  ox (s1, s2) = ((s1', s2'), o) where
    (s1', f) = fx s1
    (s2', i) = ix s2
    o   = f i

Hmm... the input doesn't go into the state update.  This can't be
right.  Let's just be done with it and make the input an existential
type also.

_app :: (a  -> s1 ->      (s1,       a  -> b)) ->
        (() -> s2 ->      (s2,       () -> a)) ->
        (() -> (s1,s2) -> ((s1, s2), () -> b)

Yeah well, I can keep permuting this but it doesn't look like it's
going to fall out.

Why doesn't this work?

Maybe because it's really a Monad?