Hey Scott

How should the result of `Vector wordType` in the "pure" variant of the function you want to implement be produced? Is that expected to come from user input?

Cheers,
Georgi

On 4/26/23 00:32, Scott Michel wrote:
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

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.