title: Can I take "snapshots" for the IO Monad?
body: <p>I am currently writing an FRP library built on Arrows (namely, <a href="https://github.com/carldong/timeless" rel="nofollow">timeless</a>). However, I encountered a problem:</p>
  
  <p>If I wrap an <code>IO</code> action inside the arrow, (<code>Signal s IO a b</code> in this case, which is a Kleisli arrow), I would like to take a "snapshot" of the final returned value, instead of running the action every time. For example, I have an action involving reading a file and parsing into some data structure, and currently this action is running every frame of update. I tried a bit to make use of Haskell's lazy evaluation to prevent it from running again and again, but it did not work.</p>
  
  <p>Conceptually, <code>Signal</code> is basically (but not exactly)</p>
  
  <pre><code>a -&gt; IO (b, Signal)
  </code></pre>
  
  <p>Each update, the signal itself is replaced by the new signal. Now, I think if I feed an <code>IO</code> action with type <code>IO a</code> in (using Kleisli arrows), I can somehow replace the <code>Signal</code> with something else that holds the final result of the previous action. However, I cannot find a way to do it because I can't extract anything from <code>IO</code>, and simply replacing the signal to a constant one doesn't seem to stop the action from being reevaluated. </p>
  
  <p>This is a minimal test program:</p>
  
  <pre><code>{-# LANGUAGE Arrows #-}
  
  module Main where
  
  import FRP.Timeless
  import Debug.Trace
  
  s1 :: (Monad m) =&gt; Signal s m a Int
  s1 = mkConst $ trace "Signal 1" $ Just 5
  s2 :: (Monad m) =&gt; Signal s m Int Int
  s2 = arr $ trace "Signal 2" (+1)
  s3 :: (Monad m) =&gt; Signal s m a ()
  s3 = arr $ \_ -&gt; ()
  
  sc = mkKleisli_ $ \_ -&gt; do
    putStrLn "SC"
    readFile "test.txt"
  sp = mkKleisli_ putStrLn
  
  box :: Signal s IO () ()
  box = proc _ -&gt; do
    file &lt;- sc -&lt; ()
    sp -&lt; file
    returnA -&lt; ()
  
  box2 = proc _ -&gt; do
    box -&lt; ()
  
  main = do
    runBox clockSession_ box2
  </code></pre>
  
  <p>Here, <code>sc</code> reads a file "Test.txt". It is evaluated every time. I would like to find a way to evaluate only once, and keep the value.</p>
  
  <p>BTW, <code>unsafePerformIO</code> would probably work, but, as its name suggests, it is probably "unsafe", so I don't want to use it</p>