Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the '\b' character in Haskell work?

Tags:

haskell

Source: Hutton, Graham. "Programming in Haskell" (p. 180)

  1. Using getCh, define an action readLine :: IO String that behaves in the same way as getLine, except that it also permits the delete key to be used to remove characters.

Hint: the delete character is ’\ DEL’, and the control character for moving the cursor back one space is ’\b’.

I solved this exercise using one '\b' character, but found online that a solver used two. Why the solver of this problem uses "\b \b" instead of "\b" ? Seems like a typo but I am unsure. I have found it works with three '\b' characters.

How does this character work ?

import System.IO

getCh :: IO Char
getCh = do
  hSetEcho stdin False
  x <- getChar
  hSetEcho stdin True
  return x

readLine :: IO String
readLine = readLine' ""

readLine' :: String -> IO String
readLine' xs = do
  x <- getCh
  case x of
    '\n' -> do
      putChar '\n'
      return xs
    '\DEL' ->
      if null xs
        then readLine' ""
        else do
          putStr "\b \b"
          readLine' (init xs)
    _ -> do
      putChar x
      readLine' (xs ++ [x])
like image 427
F. Zer Avatar asked Oct 23 '25 04:10

F. Zer


2 Answers

If you use just "\b", the cursor goes to the left but doesn't delete the character seen there until you overwrite it with a new key input. For example, FOO will end you up with fo⁁o, but that's misleading: if you don't hit another letter key but immediately , then it'll seem that the result is still foo, when actually it's only fo.

To avoid this, the solution "\b \b" moves to the left, overwrites the character with a space to visualise deleting it, and immediately moves to the left again. Together this has the same effect as moving left once and deleting the character there in-place.

like image 127
leftaroundabout Avatar answered Oct 26 '25 00:10

leftaroundabout


\b moves the cursor one character back, but it doesn't erase it (at least, not on most terminals). For example, the string abcde\b will be displayed as abcde, and the string abcde\bf as abcdf. That's why the sequence \b \b explicitly overwrites the last character with a space, and then moves the cursor back again.

like image 23
bereal Avatar answered Oct 26 '25 00:10

bereal