Tue Aug 30 18:02:41 CEST 2011
Disentangling the Arrow and Monad
Two components interact in a way I don't understnd:
* existentials for state, to be able to implement stream operator
oposition as Arrow.
* monad to implement the underlying machine language.
Some ponderings.. Why is the state existential in SigOpM? To keep
the type abstract, but at the other time guarantee that types of
initial values and state transformers match.
Can this also be accomplished using dynamics? Probably yes. Then
there can be just one type which can be a parameter for Arrow (and a
"broken" Monad) instances, and would be trivially accessible using
dynamic type casting. Are there any other pitfalls? Probably the
broken monad is good enough (problem is that a conditional can
introduce computations with different state - I'm not too happy with
The monad to implement the data sharing and possibly other machine
language constructs seems essential. However, at this time I'm using
existentials to hide term types, which I then later only convert back
Problem is I don't see what the problem is. If the state inspection
code of SigOpM is moved inside the sharing monad, the monad can be
executed to produce a result type that is compatible with stateShow.
Let's try this: stateShow will produce a Term instance, where for
ordinary "numbers" it is enough to produce Lit String. StateShow can
then be renamed to Compilable or something.
Let's revisit the point. I want to create structures that can be:
- evaluated on numbers without any issues.
- exported as syntax after abstract interpretation
Because of the "inspection" it's not possible to abstract everything.
The first requirement alone wouldn't need much, and can be very
abstract (i.e. infinite streams where the state is only implicit in
The problem I run into is that I need to *name* the state variables.
They can't just be a bunch of hidden variables.
This is possible by imposing an interface on the hidden variables, but
that somehow feels like a bit of a hack. It would be nice to be able
to hide all the details of the representation somewhere else.
Wait. It's not just that I have to hide the state type to make it an
Arrow instance. It's also that in general it is completely unknown,
so I *do* need an abstract interface, which is currently:
- label / count the nodes (generate variables)
- collect nodes in a list (collect results)
So, the fact that it is hidden is beside the (functional) point. It's
just to enable some generic Arrow sugar.
Could the state be parameterized on the "observer" type? I.e. instead
of Show a, have something like Compilable a t, where t is an observer
Let's try that out. The change doesn't seem trivial as I run into
trouble parameterizing this one:
instance (SigState a t, SigState b t) => SigState (StateProd a b) t where
stateIndex n0 (StateProd (a, b)) = (n2, (StateProd (a', b'))) where
(n1, b') = stateIndex n0 b -- Align numbering with causality through composition
(n2, a') = stateIndex n1 a
statePeek (StateProd (a,b)) = statePeek a ++ statePeek b
t is apparently ambiguous.