Thu Aug 2 13:32:46 EDT 2018


While the language is pure, it makes sense to compile TH to a monad
instead.  It can still be implemented as the identity monad and still
be fast.


This needs some thought.  I'm making several type errors in my head.
Basically, the monad should contain the memories.  First, learn how to
use fast mutable memory in haskell, then redo this:

  update =
    LamE [TupP [memIn, stateIn, inputs]] $
    DoE $
    bindings' ++
    [NoBindS $ AppE
     (VarE $ mkName "return")
     (TupE [memOut, stateOut, outputs'])]
  bindings' =
    [BindS (nodeNumPat n) (termExp e)
    | (n, e) <- partition E]

op1 :: (Int -> Int)               -> Int -> Int -> M Int
op2 :: (Int -> Int -> Int)        -> Int -> Int -> Int -> M Int 
op3 :: (Int -> Int -> Int -> Int) -> Int -> Int -> Int -> Int -> M Int

run ::
  ((m, r, [Int]) -> SeqPrim.M (m, r, [Int]),
   (m, r))
  -> [[Int]] -> SeqPrim.M [[Int]]
run (mf, (m0, r0)) is = u m0 r0 is where
  u _ _ [] = []
  u m r (i:is) = do 
    (m',r',o) <- mf (m,r,i)
    os <- u m' r' is
    return (o : os)

EDIT: I think it's doable to fix this using STUArray

But I've already reverted it.. 
Let's first build up some examples so it's clear that this works.