title: Haskell: how to use haskeline and write to a file in the same program
body: <p>I wrote a program in Haskell that builds a guitar tab as a txt file in the current directory. It gets a String of chords from the user, and then builds the proper output and writes it line by line to a file.</p>
  
  <p>I wasn't able to use the backspace key on my input when I was using getLine, because it would print a bunch of gibberish to the screen.</p>
  
  <p>I'm trying to use haskeline to fix this, and I commented out the bulk of my main method in the meantime so that each change requires less editing (every command I commented out in 'main' is of the same type as the single command I kept, so if I can get this simplified version to work, the whole thing should work). Basically, I need to be able to get the input from the user using haskeline, but then I also need to run some "side effects" commands in my "do" block after I do that.</p>
  
  <p>I'm new to Haskell and I don't fully understand what is and is not allowed or why. Here's the simplified version of my program:</p>
  
  <pre><code>import Data.List
  import System.Console.Haskeline
  
  main = runInputT defaultSettings loop
   where
     loop :: InputT IO ()
     loop  = do
       name &lt;- getInputLine "Enter name of song: "
       case name of
         Nothing -&gt; return ()
         Just songName -&gt; return ()
       chords &lt;- getInputLine "Enter chords to be tabified "
       case chords of
         Nothing -&gt; do outputStrLn $ "No chords entered. Exiting."
         Just chords -&gt; do
                          writeFile "./test.txt" "did it work?"
                          return ()
  </code></pre>
  
  <p>I got all of this syntax straight from a Haskeline tutorial. I tried running it without making any changes first and it worked, so I know that it's all correct -except- for the last 3 lines that I edited, where I have the "do" block and am trying to call "writeFile" before "return()".</p>
  
  <p>I know that the type of "loop" has to be InputT IO () in order to use getInputLine (the haskeline version of getLine), but I don't know how to accomplish "side effects" like writing to a file at the same time.</p>
  
  <p>When I try to load my project in ghci, I get the following error:</p>
  
  <pre><code>error:
  -Couldn't match type 'IO' with 'InputT IO'
   Expected type: InputT IO ()
     Actual type: IO ()
  - In a stmt of a 'd' block: writeFile "./test.txt" "did it work?"
    In the expression:
      do { writeFile "./test.txt" "did it work?";
           return () }
    In a case alternative:
      Just chords
        -&gt; do { writeFile "./test.txt" "did it work?";
                return () }
  
  Failed, modules loaded: none.
  </code></pre>