Hi,<br><br>Recently I wrote a code that uses readline library (System.Console.Readline).<br>I had to maintain a state (file path) and do IO throughout the code, so I decided to use StateT monad.<br><br>The problem was that in order to retrieve the current state (file path) inside the handler that had been registered by using bindKey function of readline, I had to resort back to using IORef rather than using the state stored in the StateT monad. It&#39;s because the handler for bindKey should have the type of Int -&gt; Char -&gt; IO Int.<br>
<br>Here is my code snippet.<br><br><br><span style="font-family: courier new,monospace;">type MyState a = StateT FilePath IO a</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">rootDir :: FilePath</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">rootDir = &quot;/root/&quot;</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">main :: IO ()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">main = do hSetBuffering stdout NoBuffering</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; execStateT (do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwd &lt;- get</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwdRef &lt;- lift $ newIORef pwd</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lift $ bindKey &#39;\t&#39; (tabHandler pwdRef)</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lift $ bindKey &#39;\^L&#39; ctlLHandler</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commandLoop pwdRef) rootDir</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ()</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">tabHandler :: IORef FilePath -&gt; Int -&gt; Char -&gt; IO Int</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">tabHandler pwdRef _ _ = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; <b><span style="color: rgb(255, 0, 0);">pwd &lt;- readIORef pwdRef</span></b></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp; insertText pwd</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; return 0</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"><br>...<br><br style="font-family: courier new,monospace;"></span><span style="font-family: courier new,monospace;">commandLoop :: IORef FilePath -&gt; MyState ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">commandLoop pwdRef = commandLoop&#39;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp; where</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp; commandLoop&#39; = do</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwd &lt;- get</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <b><span style="color: rgb(255, 0, 0);">lift $ writeIORef pwdRef pwd</span></b></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maybeLine &lt;- lift $ readline $ makePrompt $ dropTrailingPathSeparator pwd</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case maybeLine of</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nothing&nbsp;&nbsp;&nbsp;&nbsp; -&gt; return ()</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Just &quot;exit&quot; -&gt; return ()</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Just line&nbsp;&nbsp; -&gt; do</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; let tokens = words line</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case tokens of</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; []&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt; commandLoop&#39;</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (&quot;exit&quot;:_) -&gt; return ()<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&gt; do lift $ addHistory line<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processLine tokens<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; commandLoop&#39;<br>...<br><br></span><br>Is there any way in which I can do without IORef in tabHandler and commandLoop (written in red and bold, if you can see)?<br>
<br>Thanks,<br>Jinwoo<br><br><br>-- <br>Jinwoo Lee<br>Always remember that you are unique. Just like everyone else.