<div dir="ltr"><div>Thanks, that's a cool solution. Here's another thought to avoid IO. What if we're operating inside a state monad which has a list of memos. The creation function newCounter then adds a memo to the list and creates getCount as a closure with that index. The problem is that when we define the state with its list of memos, we don't know what data type each individual function will want to use. <br></div><div><br></div><div>D<br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Jul 8, 2018 at 4:15 AM, Greg Horn <span dir="ltr"><<a href="mailto:gregmainland@gmail.com" target="_blank">gregmainland@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>What about something like:</div><div><br></div><div><span style="font-size:13px">import Data.IORef ( IORef, newIORef, readIORef, writeIORef )</span></div><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">newCounter :: IO (IO Int)</span></div><div><span style="font-size:13px">newCounter = do</span></div><div><span style="font-size:13px">  counterRef <- newIORef 0 :: IO (IORef Int)</span></div><div><span style="font-size:13px">  let getCount :: IO Int</span></div><div><span style="font-size:13px">      getCount = do</span></div><div><span style="font-size:13px">        count <- readIORef counterRef</span></div><div><span style="font-size:13px">        writeIORef counterRef (count + 1)</span></div><div><span style="font-size:13px">        return count</span></div><div><span style="font-size:13px">  return getCount</span></div><div><span style="font-size:13px"><br></span></div><div><span style="font-size:13px">The user calls this function which creates the cache and returns the stateful function. You can use MVars instead of IORefs if you want it to work concurrently.</span></div></div><br><div class="gmail_quote"><span class=""><div dir="ltr">On Sun, Jul 8, 2018 at 2:29 AM Dennis Raddle <<a href="mailto:dennis.raddle@gmail.com" target="_blank">dennis.raddle@gmail.com</a>> wrote:<br></div></span><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><div dir="ltr"><div>In this one use case, there might be a simpler solution, but I have encountered lots of situations in which a particular algorithm could benefit from an associated stored cache of information. The most natural way to write an algorithm, sometimes, is in terms of its past decisions or past state of the program, interacting with current state.</div><div><br></div><div>D<br></div>​</div></span><span class="">
______________________________<wbr>_________________<br>
Haskell-Cafe mailing list<br>
To (un)subscribe, modify options or view archives go to:<br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-<wbr>bin/mailman/listinfo/haskell-<wbr>cafe</a><br>
Only members subscribed via the mailman list are allowed to post.</span></blockquote></div>
</blockquote></div><br></div>