Fri Aug 26 14:49:03 CEST 2011
I need to find a way to label the primitive state nodes. Eventually
they need to be translated to a sequence like this:
[["float", "S0", "0"],
["int", "S1", "1"], ..]
Or even lower level, untyped: address + bit pattern.
Trouble is, there is no way to access the state directly, so this
needs to be done explicitly in the form of some function.
Instead of using the initial state value to seed some computation, I
want to seed it by something that has an extra input: the label of the
So an initial state :: Double with lables indexed by :: Nat could be
Nat -> (Double, Nat)
where the output Nat represents the number of "primitive" objects
allocated. Composing the tupled version is straightforward.
Maybe the whole "state composition" operation could be abstracted
instead? Let's go for the more general operation first.
Hmm.. maybe this will give type problems..
This is what I got to work: I did not have to change anything to the
state composition: pairs are used. What I changed was just a
restriction on the state itself:
data SigOp i o = forall g s. SigOpState s => SigOp ((s, i) -> (s, o)) s
Then implemented an interface to iterate over state. The key entry
here is the instance for pairs which will "bind" the init functions.
class Show s => (SigOpState s) where
nameState :: Int -> s -> (Int, s)
-- By default, states are primitive and unchanged.
nameState n s = (n+1, s)
-- For just running, this is all we need.
initState i = snd $ nameState 0 i
instance (SigOpState a, SigOpState b) => SigOpState (a,b) where
nameState n (a,b) = (n'', (sa, sb)) where
(n', sa) = nameState n a
(n'', sb) = nameState n' b
instance SigOpState () where
nameState n () = (n, ())
instance SigOpState Int
instance SigOpState Integer
instance SigOpState Double
-- Other queries.
stateSize (SigOp _ s0) = n where
(n, _) = nameState 0 s0
Then the expression type can use named variables:
instance SigOpState Expr where
nameState n s = (n+1, I ("s" ++ show n))
cg (SigOp u s0) = show (u (initState s0, I "i"), s0, initState s0)
*Main> cg $ int . int
"(((((i + s1) + s0),(i + s1)),((i + s1) + s0)),(0,0),(s0,s1))"
*Main> cg $ int . int . int
"((((((i + s2) + s1) + s0),(((i + s2) + s1),(i + s2))),(((i + s2) + s1) + s0)),(0,(0,0)),(s0,(s1,s2)))"
Seems to work.
What about doing the same thing with inputs and outputs?