Haskell中cls函数\ESC[2J无法清屏显示[2J,如何解决?
cls Screen-Clearing Issue on Windows 10 with GHC Hey there! I’ve run into this exact problem before when working with Haskell on Windows—those ANSI escape sequences don’t play nice with the default command prompt. Let’s break down why this happens and how to fix it:
Why Your Current cls Isn’t Working
The \ESC[2J is an ANSI escape sequence used to clear screens on Unix-like terminals, but Windows’ traditional Command Prompt (cmd.exe) doesn’t support these sequences by default. That’s why you’re seeing [2J printed instead of a cleared screen. Even newer terminals like Windows Terminal might need small setup tweaks, but there are more reliable fixes available.
Solutions to Try
1. Call Windows’ Built-in cls Command (Simplest Fix)
Instead of relying on ANSI sequences, tell Haskell to run Windows’ native cls command directly. You’ll need the System.Process module:
import System.Process (callCommand) cls :: IO () cls = callCommand "cls"
This works every time because it uses Windows’ own screen-clearing command—no terminal compatibility hoops required.
2. Use the ansi-terminal Library (Cross-Platform Friendly)
If you want a solution that works seamlessly on Windows, Linux, and macOS without changing code, use the ansi-terminal library—it handles all terminal-specific logic for you.
First, install the library via Cabal:
cabal install ansi-terminal
Or if you’re using Stack:
stack install ansi-terminal
Then update your code:
import System.Console.ANSI (clearScreen) cls :: IO () cls = clearScreen
This automatically uses the right method to clear the screen no matter which OS you’re on—super clean and maintainable.
3. Enable ANSI Escape Sequences in Command Prompt (Advanced)
If you really want to stick with the original ANSI sequence approach, you can enable ANSI support in cmd.exe:
- Run
chcp 65001to set UTF-8 encoding (required for ANSI sequences to work properly) - Alternatively, set a registry key for permanent ANSI support:
- Open Registry Editor (Win + R, type
regedit) - Navigate to
HKEY_CURRENT_USER\Console - Create a new DWORD value named
VirtualTerminalLeveland set it to1
- Open Registry Editor (Win + R, type
- After this setup, your original
cls = putStr "\ESC[2J"should work as expected.
Recommendation
For most cases, either option 1 (native cls call) or option 2 (ansi-terminal library) is the way to go. Option 2 is especially great if you plan to run your code on multiple operating systems.
内容的提问来源于stack exchange,提问作者pieterinjapan

