I like the attempt to use Haskell type signatures as terse documentation. For 'tmp' it pretty nearly tells the whole story (especially rewritten flipping the first two arguments as below)<p><pre><code>  tmp :: (FilePath -&#62; IO ()) -&#62; (Stream -&#62; IO ())
  Transforms file-accepting function to work on an input stream.
</code></pre>
'keep' is a bit more ambiguous, but I think it's more clear if you write it instead as<p><pre><code>  keep :: IO a -&#62; IO [()]
</code></pre>
which has parallels to 'repeat :: a -&#62; [a]' and suggests that the first action will be "kept" and repeated periodically, throwing away the output. At this point, you have to guess when it repeats, but since you provide 'keep' no further information, blocking until files update is a pretty logical guess.