GNU ncurses is a library for creating command-line application with pseudo-graphical interfaces. This package is a nice, modern binding to GNU ncurses.
Code: https://john-millikin.com/code/haskell-ncurses (GitHub mirror)
The following example is a program that displays the message "Hello world!" until the user hits Q:
import UI.NCurses main :: IO () main = runCurses $ do setEcho False w <- defaultWindow updateWindow w $ do moveCursor 1 10 drawString "Hello world!" moveCursor 3 10 drawString "(press q to quit)" moveCursor 0 0 render waitFor w (\ev -> ev == EventCharacter 'q' || ev == EventCharacter 'Q') waitFor :: Window -> (Event -> Bool) -> Curses () waitFor w p = loop where loop = do ev <- getEvent w Nothing case ev of Nothing -> loop Just ev' -> if p ev' then return () else loop