<p>With regular Haskell values, there is no problem keeping older versions of a value around. However, <code>Handle</code>s are references to mutable resources allocated with the operating system, and carry state. After calling a version of <code>hSetBuffering</code>that returned a new <code>Handle</code>, what should happen to <em>earlier</em> versions of the <code>Handle</code> that are still kept around? Should they reflect the change? If the answer is yes, then the new-handle-returning version of <code>hSetBuffering</code> is a bit of a lie.</p>

<p>This new-handle-returning version of <code>hSetBuffering</code> could work if the type system somehow disallowed keeping old versions of the <code>Handle</code> after calling the function. It could do that by enforcing a constraint: functions that receive a <code>Handle</code> as parameter can only use that parameter <em>one single time</em>, and functions that "duplicate" handles like <code>dup :: Handle -&gt; (Handle,Handle)</code> are <em>disallowed</em>.</p>

<p>There is a (not yet accepted) <a href="https://arxiv.org/abs/1710.09756" rel="noreferrer">proposal</a> to extend Haskell with the ability to enforce such restrictions. In fact, file operations are one of the motivating examples. From section 2.3 of the paper:</p>

<pre><code>type File
openFile :: FilePath → IOL 1 File
readLine :: File ⊸ IOL 1 (File,Unrestricted ByteString)
closeFile :: File ⊸ IOL ω ()
</code></pre>

<p>Under this proposal, we can only have a single version of a <code>File</code> around at any given time. <code>closeFile</code> makes the reference to <code>File</code> unavailable so that we can't close an already closed file. Every read operation takes the previous version of the <code>File</code> and returns a new one along with the read data. And <code>hSetBuffering</code> would have a type like:</p>

<pre><code>hSetBuffering :: BufferingMode -&gt; File ⊸ IOL 1 File
</code></pre>
Why doesn't hSetBuffering return a new handle instead of changing the given handle?
<p>In Haskell, as we try to write most of our code in immutable way by not changing variables or passed parameters and instead we create a new value from the old one with required changes. </p>

<pre><code>main = do   
withFile "something.txt" ReadMode (\handle -&gt; do  
    hSetBuffering handle $ BlockBuffering (Just 2048)  
    contents &lt;- hGetContents handle  
    putStr contents)  
</code></pre>

<p>Then what is the reason than <code>hSetBuffering</code>, a function that takes a handle and sets its buffering mode, changes the passed <code>handle</code> itself instead of returning a new handle with required buffering mode?</p>