I recently tried to define a machine in the sense of Edward Kmett's Machines library with access to an efficient, mutable array for tracking its state. In order to make use of this kind of array in Haskell, you need to be in the ST monad, so I looked for a way to let a machine run in ST, and preferably without exposing this implementation detail in the machine's signature.
I didn't manage to do it. Perhaps somebody can help me with some wisdom here—I may have gotten something trivial wrong. Or it might just be that my thinking is flawed and it's just not possible. Here's the code I've got so far:
{-# LANGUAGE UnicodeSyntax, MagicHash, Unsafe, UnboxedTuples #-} -- | Given an initial ST state tag and a 'MachineT' that runs in -- 'ST', produces a pure 'Machine'. execST ∷ ∀ s k o. State# s → MachineT (ST s) k o → Machine k o execST s m = MachineT $ do let ST st = runMachineT m (# s', stp #) = st s case stp of Stop → return Stop Yield o m' → return $ Yield o (execST s' m') Await f k q → return $ Await (execST s' . f) k (execST s' q) -- | Given a 'MachineT' that runs in 'ST', produces a pure 'Machine'. execST' ∷ ∀ k o. (∀ s. MachineT (ST s) k o) → Machine k o execST' m = runST $ ST $ (\s → (# s, execST s m #))
The result of some quick testing was that a machine I ran under execST'
would reach its first yield step and then stop.
Comments
Submit a comment
Note: This website uses a JavaScript-based spam prevention system. Please enable JavaScript in your browser to post comments. Comment format is plain text. Use blank lines to separate paragraphs.