<div dir="ltr">Hello Café!<div><br></div><div>It's my first post here so do tell me if I get something wrong :)</div><div><br></div><div>I'm in the process of writing an event database; it should adhere to ACID principles and is specifically aimed at persisting then broadcasting events in some event-driven system.</div><div><br></div><div>The code is up on GitHub and I expect to build a Hackage package soon, for now I'm prototyping with Stack generating the .cabal file, but this will change when things settle down.</div><div><br></div><div>My question is about a function I have:</div><div><br></div><div><font face="courier new, monospace">readEvents :: Word64 -> Connection -> IO ([IndexedEvent], TChan IndexedEvent)<br>readEvents from conn = do<br>    (ec, chan) <- atomically $ (,)<br>        <$> (readTVar $ evCount conn)<br>        <*> (dupTChan $ readSubs conn)<br><br>    evsFromDisk <- readEventsRange from ec conn<br>    pure (evsFromDisk, chan)</font><br></div><div><br></div><div>For context please see the whole file: <a href="https://github.com/ahri/eventdb/blob/4747afb/src/Database/EventDB.hs#L172-L180">https://github.com/ahri/eventdb/blob/4747afb/src/Database/EventDB.hs#L172-L180</a></div><div><br></div><div>1. What I'd like to understand is how I might unify the return type into a single `<font face="courier new, monospace">TChan IndexedEvent`</font> which would contain first the `<font face="courier new, monospace">evsFromDisk`</font> and then pull from the broadcast channel `<font face="courier new, monospace">chan`</font>. The only way I can think to do it is to fork a thread to write to a new broadcast channel - which might be unexpected for a client of my API and seems quite heavyweight.</div><div><br></div><div>I have a connected couple of questions too, related to lazy IO as I'm still learning Haskell!</div><div><br></div><div>2. does my <font face="courier new, monospace">`readEventsRange`</font> function pull all events into memory or does lazy IO magically avoid this by streaming the data through from the disk?</div><div><br></div><div>3. if I did fork a thread and write the <font face="courier new, monospace">`evsFromDisk`</font> and the sit in a `<font face="courier new, monospace">forever</font>` reading off `<font face="courier new, monospace">chan</font>` and onto my new broadcast channel, would this result in all the written events being read into memory or does the laziness spread so that only when the client does a `<font face="courier new, monospace">readTChan</font>` will the data flow through from the disk/`<font face="courier new, monospace">chan</font>`?</div><div><br></div><div>Thanks for reading,</div><div>Adam</div></div>