[Haskell-cafe] "Hey! Monad! Leave my Pure alone!"
Scott Michel
scooter.phd at gmail.com
Tue Apr 25 21:32:24 UTC 2023
For a number of years, I've been hacking on a Z80 processor simulator, on
and off. It's generally pure code that resembles and uses State, et. al.
The design issue I've run into is adding devices to the memory system,
unsurprisingly typed as MemorySystem. Devices like to do I/O, which
potentially "pollutes" a design with Monads. So... I'm soliciting
suggestions that allow me to isolate Monadic code in the middle of pure
code (which might be Quixotic, but I'll accept that risk.)
MemorySystem uses interval maps containing memory regions, and a memory
region can be a RAMRegion, ROMRegion or DeviceRegion. The abbreviated data
declarations are:
type MemRegionMap addrType wordType = IM.IntervalMap addrType (MemoryRegion
addrType wordType)
data MemorySystem addrType wordType where
MSys ::
{ _regions :: MemRegionMap addrType wordType
} -> MemorySystem addrType wordType
data MemoryRegion addrType wordType where
EmptyRegion :: MemoryRegion addrType wordType
RAMRegion :: {- ... -}
ROMRegion :: {- ... -}
DevRegion :: {- ... -}
RAMRegion-s and ROMRegion-s are unboxed vector containers, which makes
reading and writing to them pure State code, i.e., the last two function
arguments to the reading function are "MemorySystem ... -> (Vector
wordType, MemorySystem ...)", viz:
type MemReadN addrType wordType = (Vector wordType, MemorySystem addrType
wordType)
mReadN :: addrType
-- ^ Starting address
-> Int
-- ^ Number of words to read
-> MemorySystem addrType wordType
-- ^ The memory system from which to read
-> MemReadN addrType wordType
Supporting DevRegion-s gets more complicated, because I/O is involved (we
like consoles on our machines, yes, we do.) I'd like to keep the reader
signature without unnecessarily injecting a Monad or Monad Transformer into
MemoryRegion and MemorySystem, thereby keeping the Monad or transformer
isolated in DevRegion. For example, an internal device reader function
would have a signature similar to "... -> Device m devType -> (Vector
wordType, m devType)" instead of "... -> Device m devType -> m (Vector
WordType, devType)", where "m" is the Monad or transformer.
I know, it's hard to jailbreak things out of a Monad, which may be
answering my own question. However, it seems to me that this kind of
problem occurs in real world Haskell, and I haven't encountered the real
world solution.
Ideas?
-scooter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20230425/a7468ff9/attachment.html>
More information about the Haskell-Cafe
mailing list